繁体   English   中英

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

[英]Does strtoull always return a valid number or set errno?

strtoull是否保证返回有效数字或设置errno (如果无法解析有效数字)?

换句话说,这是

errno = 0;
n = strtoull(s, 0, 10);
if (errno) {
  perror(s);
  exit(1);
}
// do something with n

正确,还是还需要进行其他检查?

没有。C 标准(至少草案 N1570 到 N2454 的§7.22.1.7,所以 C11 到 C18)只提到在一个地方设置errno

如果正确的值超出可表示值的范围,则返回LONG_MINLONG_MAXLLONG_MINLLONG_MAXULONG_MAXULLONG_MAX (根据返回类型和值的符号,如果有),宏ERANGE的值为存储在errno中。

但是,还有另一种可能的错误情况。 “如果无法执行转换,则返回零”和“ nptr的值存储在 endptr 指向的endptr中,前提是endptr不是 null 指针。” 否则,指向“最终字符串”的指针将被存储在那里,与nptr相比更大。

因此,真正符合标准的 C 程序应检查这两个条件。 这个测试程序,在 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;
}

产生 output a1: No error ,所以在这个实现中,没有设置errno

正如 chqrlie 在评论中提到的那样,检查( errno || s == unparsed )就足够了。 如果这些条件都不成立,则对非空主题序列执行了转换。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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