在这种情况下,当标记为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
图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());
我的印象是您正在重置标志,但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());
}
}