我希望代码一直运行到用户输入一个整数值。
该代码适用于char和char数组。
我已经做了以下工作:
#include<stdio.h>
int main()
{
int n;
printf("Please enter an integer: ");
while(scanf("%d",&n) != 1)
{
printf("Please enter an integer: ");
while(getchar() != '\n');
}
printf("You entered: %d\n",n);
return 0;
}
问题是,如果用户输入浮点值,scanf
将接受它。
Please enter an integer: abcd
Please enter an integer: a
Please enter an integer: 5.9
You entered: 5
如何才能避免这种情况?
9条答案
按热度按时间am46iovg1#
1.你拿
scanf()
。1.你把它扔到垃圾桶里。
1.使用
fgets()
可以得到一整行。1.使用
strtol()
将该行解析为整数,检查它是否占用了整行。nkoocmlb2#
使用
fgets
和strtol
,s
中整数表示后第一个字符的指针存储在p
指向的对象中,如果*p
与\n
不同,则输入错误。agxfikkp3#
如果您打算使用
scanf
,可以执行以下操作:q5iwbnjs4#
尝试在
scanf
中使用以下模式,它将读取到行尾:循环中不需要
getchar()
,因为scanf
将读取整行,浮点数将与scanf
模式不匹配,提示符将再次要求输入整数。vsikbqxv5#
我知道如何使用
fgets
和strtol
完成此操作,我想知道如何使用scanf()
完成此操作(如果可能)。正如其他答案所说,
scanf
并不真正适合于此,fgets
和strtol
是一种替代方案(尽管fgets
有一个缺点,即很难检测输入中的0字节,并且不可能判断0字节之后输入了什么,如果有的话)。为了完整起见(并假设有效输入是一个整数,后跟一个换行符):
或者,在
%*1[\n]
之前和之后使用%n
,并隐藏赋值。但请注意(来自Debian manpage):这不是一个转换,尽管可以使用
*
赋值隐藏字符隐藏它。C标准规定:“执行%n
指令不会增加执行完成时返回的赋值计数”,但勘误表似乎与此相矛盾。也许明智的做法是不要对%n
转换对返回值的影响做任何假设。aij0ehis6#
一个可能的解决办法是倒着想:接受浮点数作为输入,如果浮点数不是整数,则拒绝输入:
尽管这确实允许用户输入12.0或12e0等。
g9icjywg7#
使用
fgets()
更好。若要仅使用
scanf()
作为输入进行求解,请扫描int
和后面的char
。如果用户只输入空格(例如只输入Enter),此方法不会重新提示。
qpgpyjmq8#
可能不是最佳解决方案..但仅使用 scanf 和 strtol
8mmmxcuj9#
尽管通常不建议将
scanf
用于基于行的用户输入,但我将首先介绍一个使用scanf
的解决方案。此解决方案的工作原理是检查行中未被
scanf
使用的剩余字符。通常,这应该仅是换行符。但是,由于将%d
说明符与scanf
一起使用时接受前导whitespace characters,因此,如果程序也接受尾随空格字符,则会保持一致。下面是我使用
scanf
的解决方案:此程序具有以下行为:
此
scanf
解决方案存在以下问题:1.如果用户输入的数字不能表示为
int
(例如大于INT_MAX
的数字),则程序将具有undefined behavior。1.如果用户输入一个空行,它不会打印错误消息,这是因为
scanf
的%d
说明符使用了所有前导空格字符。这两个问题可以通过使用函数
fgets
和strtol
而不是函数scanf
来解决。但是,执行所有这些验证检查会使代码变得相当大。因此,将所有代码放入其自己的函数中是有意义的。下面是一个使用函数
get_int_from_user
的示例,该函数取自answer of mine to another question:此程序具有以下行为: