C 如何处理错误输入?
我想创建一个以整数为变量的程序。我想要一种方法来处理在缓冲区上扫描字符串或字符时引起的错误。我的代码如下所示:C 如何处理错误输入?,c,error-handling,scanf,C,Error Handling,Scanf,我想创建一个以整数为变量的程序。我想要一种方法来处理在缓冲区上扫描字符串或字符时引起的错误。我的代码如下所示: int输入; printf(“输入一个整数:”); scanf(“%d”,输入(&I)); 就像这样简单,但我想让程序在仍使用scanf的情况下,在缓冲区中输入“test”时打印出类似“Please enter a number”的内容,,关于scanf和%d转换说明符,需要记住两件事: %d告诉scanf跳过任何前导空格,然后读取任何十进制数字字符,直到第一个非十进制数字字符 s
int输入;
printf(“输入一个整数:”);
scanf(“%d”,输入(&I));
就像这样简单,但我想让程序在仍使用scanf的情况下,在缓冲区中输入“test”时打印出类似“Please enter a number”的内容,,关于
scanf
和%d
转换说明符,需要记住两件事:
%d
告诉scanf
跳过任何前导空格,然后读取任何十进制数字字符,直到第一个非十进制数字字符
scanf
返回成功转换和分配的项目数
scanf(“%d”,&input)
将如何根据不同的输入进行操作:
Input text Value saved to input Return value
---------- -------------------- ------------
" abc" n/a 0
" 12c" 12 1
" 1b3" 1 1
" 123" 123 1
在所有情况下,%d
转换说明符告诉scanf
跳过前导空格
如果输入的第一个非空白字符是非数字字符,scanf
将在该点停止读取,input
将不会更新,它将返回0
如果第一个非空白字符是十进制数字,scanf
将读取第一个非十进制数字字符,然后将结果数字字符串转换并分配给input
。不幸的是,这不能帮助您捕获像“12c”
或“1b3”
这样的情况-只要字符串中至少有一个十进制数字,scanf(“%d”…)
将视为成功并返回1
因此,如果要验证用户是否输入了有效的十进制整数字符串,必须执行两项操作:
scanf
的返回值李>
char dummy;
int itemsRead = scanf( "%d%c", &input, &dummy );
if ( itemsRead == 0 || itemsRead == 2 && !isspace( dummy ) )
{
fprintf( stderr, "Input is not valid, try again!\n" );
while ( getchar() != '\n' )
; // empty loop
}
如果itemsRead
为0
,则第一个输入字符不是十进制数字字符,输入不正确
如果itemsRead
是2
并且dummy
不是空白字符,那么我们会遇到类似“12c”
或“1b3”
的情况,并且输入不好
如果输入不好,则编写一条错误消息,并使用getchar
将任何剩余字符的输入流拖到下一个换行符
如果itemsRead
是1
,那么我们只在十进制数字字符后看到EOF,因此输入良好,无需其他操作。如果itemsRead
是2
并且dummy
是空白,那么输入是好的,没有其他事情可做(我假设您不需要将空白推回到输入流上)
或者,您可以将输入读取为文本,并使用strtol
将其转换为整数strtol
还将设置指向未转换的第一个字符的指针:
#define MAX_INPUT_SIZE 11 // A 32-bit integer takes up to 10 decimal digits,
// plus a possible sign character.
char buffer[MAX_INPUT_SIZE + 1]; // +1 for string terminator
if ( fgets( buffer, sizeof buffer, stdin ) )
{
char *chk;
int tmp = (int) strtol( buffer, &chk, 10 ); // convert decimal digit string
// to an integer value
if ( isspace( *chk ) || *chk == 0 )
{
input = tmp;
}
else
{
fprintf( stderr, "%s is not a valid input, try again\n", buffer );
}
}
else
{
// error on input
}
您会注意到,我将
strtol
的结果分配给了一个临时-最好在验证输入是否正确之前不要更新目标。您使用fgets()
(和strtol()
)进行用户输入。。。然后从工具箱中删除scanf()
。看看这个关于错误处理的答案:如果你想继续使用scanf
,至少你可以在这里测试这个函数的返回值是否等于1。无论出于何种目的,这个问题都不可能用scanf
解决。如果您想编写一个在错误输入时表现优雅的程序(这是一个好而高尚的目标!),那么实现它的唯一明智的方法是使用scanf
以外的技术。先看看吧scanf
无法很好地处理错误的输入,尝试添加代码以使其处理良好会遇到越来越多的困难,直到可以更容易地从其他内容开始。为什么要使用scanf
?是因为你的老师告诉你必须这样做,还是因为你觉得用C语言进行用户输入是正确的?如果你的老师坚持,我帮不了你,但如果你不这么做,请接受你想必是来寻找的专家建议,并了解scanf
基本上是可怕的。要想做任何新奇的事情,使用scanf
以外的东西比使用scanf
要容易得多。而且,不幸的是,就scanf而言,“如果用户键入错误,则提示用户”肯定算作“花哨的东西”。