为什么我的代码的一部分被跳过而且不让我输入输入?

时间:2017-02-02 05:18:24

标签: c++ string c-strings

为什么我的代码跳过了最后一个问题,当我为第一个提供了大量信息?我做错了什么?

const int SIZEC =31;
char phrase[SIZEC];
cout << " Provide a phrase, up to 30 characters with spaces. > " << endl;
cin.getline(phrase, SIZEC);
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << " The phrase is: " << phrase << endl;
cout << endl;


cout << " Using sring Class Obects " << endl;
cout << "--------------------------" << endl;
cout << endl;

string leter;
cout << " Provide a single character > " << endl;
cin >> leter;
cout << " The single character is: " << leter << endl;
cout << endl;

如果需要之前的代码告诉我,我会添加它。

2 个答案:

答案 0 :(得分:1)

使用std::string::resize作为解决方法。

string phrase;
getline(cin, phrase);
phrase.resize(30);    // phrase will be reduced to 30 chars

string letter;    // better to use char letter
cin >> letter;
letter.resize(1);

答案 1 :(得分:0)

主要问题是getline在两种情况下表现不同:

  1. 如果读取至少SIZEC个字符并且其中没有换行符(例如,应该至少有SIZEC+1个字节来存储数据读取),它会停止读取并设置所谓的流上的failbit状态位,表示“我无法读取内容,因此输入流可能不正确”。引用cplusplus.com
      

    如果函数不提取任何字符,则设置failbit标志   一旦(n-1)个字符找不到分隔字符   已写入s。

  2. 如果遇到换行符,则failbit未设置,getline成功读取并忽略换行符。
  3. 接下来发生的事情更有趣:如果输入流是bad()(即,failbitbadbit,或者提取函数(我假设它们全部都会立即失败)在流上设置eofbit。特别是,如果先前的提取操作失败,则所有后续操作也将失败。所以,基本上,如果输入的第一行无法在phrase数组中拟合,那么cin会变为“坏”,所有进一步的读取操作都不会执行任何操作。

    您可以在调用failbit之后手动重置getline来覆盖该行为,如下所示: cin.clear(); 读取操作将成功,直到另一个操作失败。

    在您的特定情况下,我假设您想要读取第一行而不管长度,然后是第二行。我就是这样,我想你 应首先检查getline是否失败(通过选中cin.failbit()cin.good()),然后不执行任何操作(如果没有,并且无需读取额外换行符)或重置failbit并忽略字符直到第一个换行符。像这样:

    #include <iostream>
    #include <limits>
    #include <string>
    
    using namespace std;
    
    int main() {
        char buf[5];
        cin.getline(buf, sizeof buf);
        if (!cin) { // operator ! is overloaded for `istream`, it's equal to `good()`
            // If stream is bad: first line of the input was truncated,
            // and following newline character was not read.
    
            // Clear failbit so subsequent read operations do something.
            cin.clear();
    
            // Read remaining of the first line.
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
        }
        // At this point, first line of the input is consumed
        // regardless of its length
        int x;
        cin >> x;
        cout << "String: |" << buf << "|\n";
        cout << "x: " << x << "\n";
    }
    

    您可以在StackOverflow herethere上阅读更多内容。

    但是,如果没有理由将C风格的字符串与istream一起使用,我建议您改为使用stringstd::getline(例如Shreevardhan's answer });它将产生更清晰的代码,并且不会有额外的情况。