我正在学习C ++。
nav是整数。
如果他/她输入无效值,我想要求用户输入有效值。
void main()
{
printf("Type an integer : ");
if(!scanf("%d", &nav))
{
system("cls");
printf("Invalid ! \n");
main();
}
}
但输入第一个值后它会闪烁。它像重装屏幕一样闪烁。我认为这是无限循环。
我怎么能以正确的方式做到这一点?我想问用户的号码,直到它输入一个实数。
答案 0 :(得分:3)
如果用户键入无效输入,scanf()
将不会消耗它,并且您将永远偷看相同的违规输入字符。您需要先阅读用户输入的内容 - 我建议您使用std::getline()
- 然后尝试使用strtol()
,sscanf()
或std::istringstream
进行解析。请勿使用atoi()
,因为它不会报告失败。
int nav;
{
string line;
while (getline(cin, line))
if (istringstream(line) >> nav)
break;
}
编辑:请参阅评论,了解上述逻辑的相当漂亮的演绎。我把它排除在答案之外是因为:a)我不想偷别人的想法,而且b)我不确定我是否会以这种方式呈现C ++的新手 - 不是一次性的,不是至少
P.S。:您无法在C ++中调用main()
。
答案 1 :(得分:1)
两件事。
Scanf在处理输入之前需要按下“enter”键,因此闪烁可能就是光标等待下一个键。
另外,从main调用main是相当不标准的。你应该看一下'while'循环。
答案 2 :(得分:0)
你的节目不是很好,但我会告诉你发生了什么。
在C / C ++中,当scanf
无法从输入读取整数(%d
)时,它不会读取任何内容。也就是说,无论阻止scanf
读取int,都将保留在那里。在下一个scanf
,相同的字符将导致错误。
让我举一个例子来证明。想象一下,你正在从这个输入中读取许多整数:
12 13 Shahbaz 15
现在,如果您使用scanf
致电%d
,则会看到12
,输入内容为:
13 Shahbaz 15
接下来,您使用scanf
致电%d
,然后阅读13
。现在输入将是:
Shahbaz 15
再次,您使用scanf
致电%d
。这里,输入以S
(在空白之后)开始,使scanf
返回失败,因为它无法读取整数。输入保持不变(可能保存为空白)。也就是说,输入将是:
Shahbaz 15
正如您所看到的,使用%d
读取输入将给出完全相同的错误,并且您陷入了无限循环。
要解决这个问题,你有很多选择。这在很大程度上取决于您希望如何处理这种情况,但有两种方法是在打印%c
后立即读取字符(带%s
)或字符串(带printf("Invalid\n")
)
第一种方法适合处理这样的输入:
12 13 q14 15
其中q
是一个需要忽略的错误。第二种方法适合处理这样的输入:
12 13 Shahbaz 15
无效数据是有意义的单词,但您只想忽略它们。
如果我想使用scanf
,那么我会写它的方式是:
int main() // always write int main
{
int nav;
printf("Type an integer: ");
while (scanf("%d", &nav) != 1) // scanf returns number of successful %'s read
{
printf("Invalid number. Try again: ");
scanf("%*s"); // read a %s but ignore it
}
// The rest of the program, using nav
return 0;
}