简体   繁体   English

strtoull 是否总是返回有效数字或设置 errno?

[英]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 , or ULLONG_MAX is returned (according to the return type and sign of the value, if any), and the value of the macro ERANGE is stored in errno .如果正确的值超出可表示值的范围,则返回LONG_MINLONG_MAXLLONG_MINLLONG_MAXULONG_MAXULLONG_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM