在 C 语言中,对于存放错误码的全局变量 errno,相信大家都不陌生。为防止和正常的返回值混淆,系统调用一般并不直接返回错误码,而是将错误码(是一个整数值,不同的值代表不同的含义)存入一个名为 errno 的全局变量中,errno 不同数值所代表的错误消息定义在 文件中。如果一个系统调用或库函数调用失败,可以通过读出 errno 的值来确定问题所在,推测程序出错的原因,这也是调试程序的一个重要方法。
配合 perror 和 strerror 函数,还可以很方便地查看出错的详细信息。其中:
perror 在 中定义,用于打印错误码及其消息描述;
strerror 在 中定义,用于获取错误码对应的消息描述;
需要特别强调的是,并不是所有的库函数都适合使用 errno 全局变量。就 errno 而言,库函数一般分为如下 4 种类型。
1) 设置errno并返回一个带内“In-Band”错误指示符的库函数
表1 设置 errno 并返回一个带内“In-Band”错误指示符的库函数
函 数
返回值
errno 值
fgetwc、fputwc
WEOF
EILSEQ
strtol、wcstol
LONG_MIN 或 LONG_MAX
ERANGE
stitoll、wcstoll
LLONG_MIN 或 LLONG_MAX
ERANGE
stitoul、wcstoul
ULONG_MAX
ERANGE
stitoull、wcstoull
ULLONG_MAX
ERANGE
stitoumax、wcstoumax
UINTMAX_MAX
ERANGE
strtod、wcstod
0 或 ±HUGE_VAL
ERANGE
strtof、wcstof
0 或 ±HUGE_VALF
ERANGE
strtold、wcstold
0 或 ±HUGE_VALL
ERANGE
stitoimax、wcstoimax
INTMAX_MIN、INTMAX_MAX
ERANGE
如表 1 所示,这些函数将设置 errno,并返回一个带内“In-Band”错误指示符。例如,函数 strtoul 发生错误时将返回 ULONG_MAX,并将 errno 的值设置为 ERANGE。这里就需要注意了,由于 ULONG_MAX 也是一个合法的返回值,因此必须使用 errno 来检查是否发生错误。与此同时,对于这类函数,必须在调用这些库函数之前将 errno 的值设置为 0,然后在调用库函数之后检查 errno 的值。
2) 设置 errno 并返回一个带外“Out-of-Band”错误指示符的库函数
表 2 设置 errno 并返回一个带外“Out-of-Band”错误指示符的库函数
函 数
返回值
errno 值
ftell()
-1L
positive
fgetpos()、fsetpos()
nonzero
positive
mbitowc()、mbsrtowcs()
(size