C - 无法读取用户整数输入
C - Can't read user integer input
我正在尝试使用以下代码读取用户整数输入。我知道 strtol returns 是一个很长的值。
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 != '[=10=]'){
printf("You didn't enter a number.\n");
}
else{
printf("%d\n", color);
}
}
我尝试了 运行 这个,首先输入 4,这给了我 You didn't enter a number.
我用 "forty" 再次尝试并得到相同的结果。我在这里错过了什么?我想要做的就是获取一个整数值的基本用户输入,以验证是否只输入了一个整数。我不需要很长时间,因为值都在 3000 到 4000 之间。
将 if(last != '[=10=]')
更改为 if( *last != '[=11=]')
。你想检查什么 last
指向
来自https://linux.die.net/man/3/strtol
If endptr is not NULL, strtol() stores the address of the first
invalid character in *endptr. If there were no digits at all, strtol()
stores the original value of nptr in *endptr (and returns 0).
In
particular, if *nptr is not '[=13=]' but **endptr is '[=13=]' on return, the
entire string is valid.
last != '[=13=]'
等同于 last != NULL
。您正在测试 last
是否是空指针,但它从来都不是,因为 strtol
永远不会将 *endptr
设置为 NULL
.
您或许应该这样做:
if (last == buf || *last != '[=10=]')
(第一个条件处理 buf
为空字符串的情况。)
您的输入代码存在次要问题:
fgets(buf, 256, stdin);
此行不检查 fgets
的 return 值以确保 buf
已填充,并且不删除任何用户输入的尾随换行符。
改为这样做:
if (!fgets(buf, 256, stdin)) {
break;
}
buf[strcspn(buf, "\n")] = '[=12=]';
至于为什么'[=22=]'
在这里充当空指针:
如果在指针上下文中使用,任何值为零的整数常量表达式都将隐式转换为空指针。 '[=22=]'
是这样一个零值整数表达式,您将它与指针进行比较,因此它在指针上下文中。
对于 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 != '[=10=]'){
if (*last || color < 3000 || color > 4000) {
Handle_NonNumeric("You didn't enter a number in 3000-4000 range.\n");
} else {
foo(color); // Success
}
我正在尝试使用以下代码读取用户整数输入。我知道 strtol returns 是一个很长的值。
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 != '[=10=]'){
printf("You didn't enter a number.\n");
}
else{
printf("%d\n", color);
}
}
我尝试了 运行 这个,首先输入 4,这给了我 You didn't enter a number.
我用 "forty" 再次尝试并得到相同的结果。我在这里错过了什么?我想要做的就是获取一个整数值的基本用户输入,以验证是否只输入了一个整数。我不需要很长时间,因为值都在 3000 到 4000 之间。
将 if(last != '[=10=]')
更改为 if( *last != '[=11=]')
。你想检查什么 last
指向
来自https://linux.die.net/man/3/strtol
If endptr is not NULL, strtol() stores the address of the first invalid character in *endptr. If there were no digits at all, strtol() stores the original value of nptr in *endptr (and returns 0).
In particular, if *nptr is not '[=13=]' but **endptr is '[=13=]' on return, the entire string is valid.
last != '[=13=]'
等同于 last != NULL
。您正在测试 last
是否是空指针,但它从来都不是,因为 strtol
永远不会将 *endptr
设置为 NULL
.
您或许应该这样做:
if (last == buf || *last != '[=10=]')
(第一个条件处理 buf
为空字符串的情况。)
您的输入代码存在次要问题:
fgets(buf, 256, stdin);
此行不检查 fgets
的 return 值以确保 buf
已填充,并且不删除任何用户输入的尾随换行符。
改为这样做:
if (!fgets(buf, 256, stdin)) {
break;
}
buf[strcspn(buf, "\n")] = '[=12=]';
至于为什么'[=22=]'
在这里充当空指针:
如果在指针上下文中使用,任何值为零的整数常量表达式都将隐式转换为空指针。 '[=22=]'
是这样一个零值整数表达式,您将它与指针进行比较,因此它在指针上下文中。
对于 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 != '[=10=]'){
if (*last || color < 3000 || color > 4000) {
Handle_NonNumeric("You didn't enter a number in 3000-4000 range.\n");
} else {
foo(color); // Success
}