新C程序员面临的最大问题之一是正确处理用户输入,尤其是在使用
scanf
你
必须说明输入缓冲区中剩余的所有字符(
stdin
这里)如果
匹配失败
. 为什么?当
匹配失败
发生,
扫描
在故障点停止处理字符,而导致故障的字符仍保留在输入缓冲区中
未读
使问题更加复杂的是,两者之间的区别是什么
扫描
处理空白。数字输入说明符和
%s
%s码
'\n'
在尝试下一个字符或
也就是说,每当你使用
扫描
检查回路
因此,您可以确定用户是否使用手动生成的
EOF
是否
匹配
或
输入
发生故障。
int
,您必须检查退货是否正确
1
使用前
value
. 否则您可以轻松调用
未定义的行为
. 现在,仅仅检查是否发生了所有转换不允许您区分
EOF公司
或
#include <stdio.h>
int main (void) {
int value = 0;
while (value >= 0) {
printf("Enter a number: ");
if (scanf("%d",&value) != 1) {
fputs ("error: invalid input\n", stderr);
return 1;
}
printf("The number you entered is %d\n", value);
}
return 0;
}
使用/输出示例
$ ./bin/scanfpos2
Enter a number: 1
The number you entered is 1
Enter a number: 10
The number you entered is 10
Enter a number: foo
error: invalid input
(
注:
匹配
发生故障,如果故障是一个错误,您可以通过清空输入缓冲区来采取适当的操作继续
匹配
处理输入的正确方法
扫描
是覆盖所有潜在的错误条件,并优雅地响应
匹配
标准
扫描
/** remove all characters that remain in stdin */
void empty_stdin (void)
{
int c = getchar();
while (c != '\n' && c != EOF)
c = getchar();
}
它只读取
标准
'\n'
或
EOF公司
遇到。再加上一个关于
扫描
将允许您处理
匹配
优雅地失败。
#include <stdio.h>
/** remove all characters that remain in stdin */
void empty_stdin (void)
{
int c = getchar();
while (c != '\n' && c != EOF)
c = getchar();
}
int main (void) {
int value = 0;
while (value >= 0) {
int rtn; /* variable to store return on scanf */
printf ("Enter a number: ");
rtn = scanf ("%d",&value);
if (rtn == EOF) { /* handle EOF */
fputs ("user canceled input.\n", stderr);
break;
}
else if (rtn == 0) { /* handle matching/input failure */
fputs ("error: invalid input\n", stderr);
empty_stdin();
}
else /* good input - output value */
printf("The number you entered is %d\n", value);
}
return 0;
}
$ ./bin/scanfpos2
Enter a number: 1
The number you entered is 1
Enter a number: 10
The number you entered is 10
Enter a number: foo
error: invalid input
Enter a number: -1
The number you entered is -1
这里如果一个非整数
foo
标准
仔细看看。C不是python。Python对您隐藏了许多实现细节,以从本质上保护您不受实例的影响,但它也有其缺点。有了C,你什么都不知道。您可以自由地写入不属于自己的内存,在转换失败后重复尝试从输入缓冲区读取数据,等等。。你对细节负责。
最后,所有这一切都是我们接受意见的主要原因
fgets
getline
建议新用户使用。有足够大的缓冲区(不要吝啬大小),
fgets公司
将一次从输入缓冲区中读取一行,防止有问题的字符继续等待再次咬你。
getline公司
扫描
. 你可以随时打电话
sscanf