我想了解这个项目:
Why is my program ignoring my input request after the first iteration?
来自C ++ FAQ。
我编译了测试程序:
#include <iostream>
int main()
{
char name[1000];
int age;
for (;;)
{
std::cout << "Name: ";
std::cin >> name;
std::cout << "Age: ";
std::cin >> age;
}
return 0;
}
一切似乎都运转良好。然而,作者说有一个问题:
因为数字提取器在输入中留下了非数字 缓冲液中。
并且正确的源代码应为:
int main()
{
char name[1000];
int age;
for (;;)
{
std::cout << "Name: ";
std::cin >> name;
std::cout << "Age: ";
std::cin >> age;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
return 0;
}
请您解释一下该计划的预期行为,以及如何解决不良行为?
编辑:
问题是我没想到程序应该处理错误,例如在预期数字输入时输入10b
。实际上,作者的修改处理了这样的错误,但是没有处理用户输入错误的错误。 b10
。
答案 0 :(得分:2)
在第一个例子中,如果您为名称输入a,然后输入10b作为年龄,则程序的输出为
Name: a
Age: 10b
Name: Age:
现在我们得到这个的原因是10b中的b留在流中,然后下次std::cin >> name;
被调用它抓住b并继续询问年龄。在第二个例子中,std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
将删除数字后的字母,程序将正常运行。
答案 1 :(得分:1)
在您的第一个代码中,对于age
,如果您输入的是字符而不是数字,那么cin
会将其保留在输入流中,而下一个cin
会尝试读取那。所以,它不需要输入。
让我们简单地运行代码,进行for循环的三次迭代,
输入和输出
Name: ar
Age: a
Name: Age:
Name: Age:
如您所见,如果您为age
输入字符,则不会再向用户询问值。要防止这种情况,并刷新缓冲区以清除缓冲区中不需要的字符,请使用
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
但我个人认为使用cin.clear();
也是一件好事。
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
这将消除缓冲区中所有剩余的不需要的字符。
答案 2 :(得分:0)
考虑以下代码:
int main()
{
char name[1000];
int age;
char name2[1000];
std::cout << "Name: ";
std::cin >> name;
std::cout << "Age: ";
std::cin >> age;
std::cin >> name2;
std::cout << "Name: \"" << name << "\"" << std::endl;
std::cout << "Age: \"" << age << "\"" << std::endl;
std::cout << "Name2: \"" << name2 << "\"" << std::endl;
return 0;
}
如果您输入:
John
23 Doe
name2作为Doe
读入。如果您在阅读age
和name2
之间执行代码,可能会发生奇怪的事情。通过清除读取之间的缓冲区,这不会发生。