[英]Does strtoull always return a valid number or set errno?
Is strtoull
guaranteed to either return a valid number, or set errno
(if no valid number could be parsed)? strtoull
是否保证返回有效数字或设置errno
(如果无法解析有效数字)?
In other words, is this换句话说,这是
errno = 0;
n = strtoull(s, 0, 10);
if (errno) {
perror(s);
exit(1);
}
// do something with n
correct, or is some other check also required?正确,还是还需要进行其他检查?
No. The C standard (§7.22.1.7 of at least drafts N1570 through N2454, so C11 through C18) only mentions setting errno
in one place:没有。C 标准(至少草案 N1570 到 N2454 的§7.22.1.7,所以 C11 到 C18)只提到在一个地方设置
errno
:
If the correct value is outside the range of representable values,
LONG_MIN
,LONG_MAX
,LLONG_MIN
,LLONG_MAX
,ULONG_MAX
, orULLONG_MAX
is returned (according to the return type and sign of the value, if any), and the value of the macroERANGE
is stored inerrno
.如果正确的值超出可表示值的范围,则返回
LONG_MIN
、LONG_MAX
、LLONG_MIN
、LLONG_MAX
、ULONG_MAX
或ULLONG_MAX
(根据返回类型和值的符号,如果有),宏ERANGE
的值为存储在errno
中。
There is another possible error condition, however.但是,还有另一种可能的错误情况。 “If no conversion could be performed, zero is returned,” and “the value of
nptr
is stored in the object pointed to by endptr
, provided that endptr
is not a null pointer.” “如果无法执行转换,则返回零”和“
nptr
的值存储在 endptr 指向的endptr
中,前提是endptr
不是 null 指针。” Otherwise, a pointer to “the final string” would be stored there, which would compare greater to nptr
.否则,指向“最终字符串”的指针将被存储在那里,与
nptr
相比更大。
Therefore, a truly standard-compliant C program should check both conditions.因此,真正符合标准的 C 程序应检查这两个条件。 This test program, compiled with
clang -std=c18
on Windows 10:这个测试程序,在 Windows 10 上使用
clang -std=c18
编译:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
int main (void) {
const char s[] = "a1";
errno = 0;
char* unparsed = NULL;
const unsigned long long int n =
strtoull( s, &unparsed, 10 );
if ( errno || (!n && s == unparsed) ) {
fflush(stdout); // Don't cross the streams!
perror(s);
exit(EXIT_FAILURE);
}
printf( "%llu\n", n );
return EXIT_SUCCESS;
}
produces the output a1: No error
, so on this implementation, errno
is not set.产生 output
a1: No error
,所以在这个实现中,没有设置errno
。
As chqrlie brings up in the comments, it would have sufficed to check ( errno || s == unparsed )
.正如 chqrlie 在评论中提到的那样,检查
( errno || s == unparsed )
就足够了。 If neither of these conditions hold, there was a conversion performed on a non-empty subject sequence.如果这些条件都不成立,则对非空主题序列执行了转换。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.