【问题标题】:Checking if command line input is valid integer (C)检查命令行输入是否为有效整数 (C)
【发布时间】:2015-04-12 15:54:19
【问题描述】:

我正在尝试验证我的程序的用户是否在命令行中输入了一个有效的整数。我遇到了一个问题:它拒绝所有输入。

这就是我所拥有的

// Make sure input is a valid int
char *ptr = NULL;
long int input = strtol(argv[i+1], &ptr, 10);
if(ptr == NULL){
    userMinInt = input;
    minIntSet = true;    
}
else
    fprintf(stderr, "You must enter a valid integer for <min-int>. Using default value of %ld\n", minInt);

【问题讨论】:

  • 我认为stackoverflow.com/questions/19206660/… 回答了这个问题。
  • @peter 啊,我明白了。所以你不检查 null 你检查 (char)0;
  • i 是什么?确保在执行此操作之前检查i + 1 &lt; argc
  • @MattMcNabb 这是在 for(int i = 0; i
  • @JayB argv[argc] 始终为空,因此您将在最后一次循环迭代中读取空指针。要解决此问题,请将循环条件设为 i + 1 &lt; argc

标签: c string char integer command-line-arguments


【解决方案1】:

感谢彼得,我已经解决了这个问题。这是新的工作代码:

// Make sure input is a valid int
char *ptr = NULL;
long int input = strtol(argv[i+1], &ptr, 10);
if(ptr != NULL && *ptr == (char)0){
    userMinInt = input;
    minIntSet = true;
}
else
    fprintf(stderr, "You must enter a valid integer for <min-int>. Using default value of %ld\n", minInt);

【讨论】:

  • 强制转换是不必要的,您可以在不改变程序行为的情况下删除它。
  • @MattMcNabb Isnt (int)0 等于 C 中的 NULL?
  • 不完全是。 NULL 是一个可以扩展为0 或(void *)0 的宏,它应该用在需要指针的地方。不过,这与*ptr == 0 无关。
【解决方案2】:

代码正在检查结束指针是否为NULL。相反,代码应该检查:

1) 结束指针是否指向空字符'\0'?
2)结束指针与开始不同吗?

以下附加检查:

char *start = argv[i+1];  // maybe should be argv[i]
char *ptr;
// set errno to 0 for subsequent check
errno = 0;
long int input = strtol(start, &ptr, 10);
if (ptr == start) {
  fprintf(stderr, "No conversion done.\n");
}
else if (*ptr != 0) {
  fprintf(stderr, "Extra data after the number.\n");
}
else if (errno) {
  fprintf(stderr, "Number outside long range.\n");
}
else if (input < INT_MIN || input > INT_MAX) {
  fprintf(stderr, "Number %ld outside int range.\n", input);
}
else {
  printf("Number is %d.\n", (int) input);
}

【讨论】:

  • 我认为,if(errno) 应该是 if((input == LONG_MIN || input == LONG_MAX) &amp;&amp; errno == ERANGE) -- errno 可能会在成功时更改。
  • @mafso 同意提议的if() 可行,但不同意它的需要。对strtol() 的调用将errno 设置为范围错误,否则不会更改:“无论是否存在错误,库函数调用都可以将errno 的值设置为非零,前提是使用errno 未记录在本国际标准的功能描述中。” C11 §7.5 3 和 strtol() 规范包括:“...如果正确的值超出可表示值的范围,...并且宏 ERANGE 的值存储在 errno 中。” §7.22.1.4
  • 有趣。 Linux 联机帮助页似乎与此相矛盾(尤其是代码示例)。也许标准 C 函数和 POSIX 或 GNU 函数不同?无论如何,我对这里的这个案子深信不疑。谢谢!
  • @mafso 我审查了linux.die.net/man/3/strtol 并同意你关于errno 的含义/处理的一些潜在矛盾,但没有找到任何支持“errno 可能会在成功时更改” .确实发现:“通过在调用后检查errno 是否具有非零值来确定是否发生错误。” (IAC,这听起来是一个很好的 SO 问题。)
  • 来自linux.die.net/man/3/errno:“成功的函数被允许更改errno。” [嗯。不是我的] 我会看看 POSIX 和一些联机帮助页,尝试 glibc 中的一些函数,看看我是否可以写一个问题(如果你不打算这样做的话)。
猜你喜欢
  • 2015-05-28
  • 1970-01-01
  • 2016-05-25
  • 1970-01-01
  • 1970-01-01
  • 2023-03-15
  • 2016-05-19
相关资源
最近更新 更多