【问题标题】:Why cin>>(string) stopped after cin>>(int) failed?为什么 cin>>(string) 在 cin>>(int) 失败后停止?
【发布时间】:2021-12-15 11:51:26
【问题描述】:

当调用cin>>(int) 和cin>>(string) 时,当第一个输入对于整数不正确时,似乎cin>>(string) 将无法检索第二个输入,即使它是正确的字符串。

源码简单如下:

cout<<"Please enter count and name"<<endl;;
int count;
cin>>count;     // >> reads an integer into count
string name;
cin>>name;      // >> reades a string into name

cout<<"count: "<<count<<endl;
cout<<"name: "<<name<<endl;

测试用例是:

案例1:输入字符(不适合int)和字符

请输入人数和姓名

广告位

计数:0

姓名:

案例 2:输入数字和字符

请输入人数和姓名

30 广告

计数:30

名称:广告

案例3:输入数字和数字(可以当作字符串)

请输入人数和姓名

20 33

计数:20

名称:33

【问题讨论】:

  • std::cin 有一个可以检查的状态,例如通过std::cin.good()。输入可能会失败,而且经常会失败,所以你需要做点什么
  • 第一次使用 cin 的状态/结果如何影响 cin 的第二次使用?还是说每次使用cin之前都需要检查或清除cin的状态?我从未在代码中看到任何对 cin 状态的预处理。谢谢。
  • @lst 1) "第一次使用 cin 的状态/结果如何影响第二次使用 cin?" 如果 cin 处于无效状态,任何进一步的操作是没有意义的。 2) “或者这是否意味着在每次使用 cin 之前,需要检查或清除 cin 的状态?” 是的,需要养成检查操作是否成功的习惯,而不是假设它们做过。 3)“我从未见过代码中cin状态的任何预处理if (cin&gt;&gt;count) {/* operation succeeded */ }

标签: c++ cin


【解决方案1】:

流有一个内部错误标志,一旦设置,它就会一直保持设置,直到您明确清除它。当读取失败时,例如因为无法将输入转换为所需的类型,所以设置了错误标志,只要不清除此标志,甚至不会尝试任何后续的读取操作:

int main() {

    stringstream ss("john 123");

    int testInt;
    string testString;

    ss >> testInt;
    if (ss) {
        cout << "good!" << testInt << endl;
    } else {
        cout << "bad!" << endl;
    }

    ss >> testString;
    if (ss) {
        cout << "good!" << testString << endl;
    } else {
        cout << "bad!" << endl;
    }

    ss.clear();
    ss >> testString;
    if (ss) {
        cout << "good:" << testString << endl;
    } else {
        cout << "bad!";
    }
}

输出:

bad!
bad!
good:john

【讨论】:

  • 随便找一个类似这个问题的帖子:stackoverflow.com/a/39282970/8641405
  • 它提到了 cin.clear() 和 cin.ignore()。是不是意味着在某些情况下,例如流中有多个错误输入,我们必须调用 cin.ignore(streamsize, delim) 来清除 cin 缓冲区?
  • 我已经尝试过 cin.clear() 和 cin.ignore() 并且还找到了另一个关于如何处理的链接
  • 我已经尝试过 cin.clear() 和 cin.ignore() 并且还找到了另一个链接,讨论如何处理要提取的最大字符数并提供分隔符。 [链接]stackoverflow.com/questions/257091/… 及以下代码似乎有效:int id; cout>id)) { cin.clear(); cin.ignore(numeric_limits::max(), '\n'); }
【解决方案2】:

你可以用

检查输入语句是否成功

cin.good() 方法

如果输入语句失败,则返回 false,否则返回 true。这是一个小例子:

#include <iostream>
#include <cstdlib>

using namespace std;

int main()
{
  int x; 

  // prompt the user for input 
  cout << "Enter an integer: " << "\n"; 
  cout << "cin.good() value: " << cin.good() << "\n";
  // get input 
  cin >> x; 
  cout << "cin.good() value: " << cin.good() << "\n";
  // check and see if the input statement succeeded 
  if (!cin) { 
    cout << "That was not an integer." << endl; 
    return EXIT_FAILURE; 
  } 

  // print the value we got from the user 
  cout << x << endl; 
  return EXIT_SUCCESS; 
}

输出:

Enter an integer: 
cin.good() value: 1
asd
cin.good() value: 0
That was not an integer.

【讨论】:

  • if (cin.good() == false) is a long-winded way of writing if (!cin). The usual idiom for testing stream states is to use the boolean conversion: if (cin)`看好坏,if (!cin)看好坏。
  • 感谢您的更正 :) 我更新了我的答案。
  • 在我挑剔你的同时,请注意-1 不一定是从main 返回的有意义的值。您可以返回EXIT_SUCCESS0 表示成功,或返回EXIT_FAILURE 表示失败。这些宏在&lt;cstdlib&gt; 中定义。任何其他值的含义由实现定义。
  • 这很好,因为我也学到了一些新东西:D 我更新了答案。
  • @TiborFekete 我想解决 cin 坏状态,也可以刷新错误读入的数据,代码 cin.clear();和 cin.ignore(numeric_limits::max(), '\n');似乎工作。我指的是[链接]stackoverflow.com/questions/257091/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-12-02
  • 2018-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-13
相关资源
最近更新 更多