在这种情况下,当标记为hang point
的行收到无效输入时,例如。 abc
,它重复内部do-while循环,并在再次到达该行时挂起。
// figure 1
std::string s;
do {
do {
std::cout<<"s = ";
std::getline(std::cin, s);
} while (s == "");
double d;
std::cout<<"d = ";
do {
std::cin.clear();
std::cin>>d; // hang point
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
} while (std::cin.fail());
} while (s != "exit");
在这种情况下,程序跳过该行并永远重复执行do-while循环。
// figure 2
double d;
do {
std::cout<<"d = ";
std::cin.clear();
std::cin>>d; // skip point
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
} while (std::cin.fail());
为什么?
最初我会问为什么figure 1
挂起,并且在尝试简化示例的过程中,我提出了figure 2
,并发现它没有挂起,而是永远重复。我不明白为什么figure 1
或figure 2
做他们做的事情。
编辑:我在我为自己写的提示中输入字母数据,导致cin
失败。例如
s = something
d = 3
s = something
d = a
答案 0 :(得分:2)
图2:你必须在cin.ignore()之前调用cin.clear()。否则,cin.ignore将不会执行任何操作,因为cin仍处于错误状态。
double d;
do {
if (std::cin.fail()) {
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
std::cout<<"d = ";
std::cin>>d;
} while (std::cin.fail());
答案 1 :(得分:1)
我的印象是你正在重置标志,但是cin缓冲区仍然是满的。因此,当它重新进入循环时,'d'会自动重新分配字母值(例如,您在终端输入的'abc')。因此,失败标志将被重置,循环将重复。
这是固定版本(有一些风格上的变化,抱歉):
#include <string>
#include <iostream>
int main(){
std::string s="";
std::string dummy="";
while ( s!="exit"){
s="";
while (s==""){
std::cout<<"s = ";
std::getline(std::cin, s);
}
double d;
std::cout<<"d = ";
do {
if (std::cin.fail()){
std::cin.clear();
std::getline(std::cin, dummy);
std::cout << "d = ";
}
std::cin>>d;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
} while (std::cin.fail());
}
}