Std::cin有时挂起,有时在无效输入后永远重复

  • 本文关键字:永远 cin 挂起 Std 无效 c++
  • 更新时间 :
  • 英文 :


在这种情况下,当标记为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 1figure 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());
    }
}

最新更新