我尝试使用以下代码读取用户整数输入。我知道strtol会返回一个很长的值。
long color = 1;
char buf[256];
char * last;
while(color != 0){
printf("Enter a color (0 to stop): ");
fgets(buf, 256, stdin);
color = strtol(buf, &last, 10);
if(last != '\0'){
printf("You didn't enter a number.\n");
}
else{
printf("%d\n", color);
}
}
我尝试运行此操作,首先输入4,这给了我You didn't enter a number.
我再次尝试使用"四十"并得到了相同的结果。我在这里错过了什么?我想要做的就是获得一个整数值的基本用户输入,该值只验证输入的整数。我不需要很长时间,因为价值将在3000到4000之间。
答案 0 :(得分:0)
将if(last != '\0')
更改为if( *last != '\0')
。您想查看last
指向的内容
来自https://linux.die.net/man/3/strtol
如果endptr不为NULL,则strtol()存储第一个地址 * endptr中的无效字符。如果根本没有数字,strtol() 将nptr的原始值存储在* endptr中(并返回0)。
在 特别是,如果* nptr不是'\ 0'但是** endptr在返回时是'\ 0',那么 整个字符串都有效。
答案 1 :(得分:0)
last != '\0'
相当于last != NULL
。您正在测试last
是否为空指针,它永远不会,因为strtol
从未将*endptr
设置为NULL
。
你应该这样做:
if (last == buf || *last != '\0')
(第一个条件处理buf
为空字符串的情况。)
输入代码中存在次要问题:
fgets(buf, 256, stdin);
此行不会检查fgets
的返回值以确保buf
已填充,并且不会删除任何用户输入的尾随换行符。
请改为:
if (!fgets(buf, 256, stdin)) {
break;
}
buf[strcspn(buf, "\n")] = '\0';
至于为什么'\0'
在这里充当空指针:
如果在指针上下文中使用,则任何值为零的整型常量表达式都会隐式转换为空指针。 '\0'
是一个零值整数表达式,您将它与指针进行比较,因此它位于指针上下文中。
答案 2 :(得分:0)
对于OP的特定情况,在数字后测试额外的非数字文本就足够了。
char buf[256];
if (fgets(buf, sizeof buf, stdin)) Handle_EndOfFile();
char *last;
long color = strtol(buf, &last, 10);
while (isspace(*last)) last++; // tolerate trailing white-space like '\n'
// Do not compare the pointer, compare what it points to
// if(last != '\0'){
if (*last || color < 3000 || color > 4000) {
Handle_NonNumeric("You didn't enter a number in 3000-4000 range.\n");
} else {
foo(color); // Success
}