为啥我的部分代码被跳过而不让我输入输入?

Posted

技术标签:

【中文标题】为啥我的部分代码被跳过而不让我输入输入?【英文标题】:Why is part of my code being skipped and not letting me enter input?为什么我的部分代码被跳过而不让我输入输入? 【发布时间】:2017-02-02 05:18:23 【问题描述】:

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

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;

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

【问题讨论】:

我的老师希望它是一个字符串.. :( don't use endl 除非您知道并需要它的副作用 嗯。什么“副作用”?它对我来说效果很好......从来没有问题。 请在询问之前阅读链接 【参考方案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);

【讨论】:

第一个是 cstring,它必须保持这种状态......我可能也应该添加它。当我尝试“phrase.resize(30)”时出现错误。我认为这是因为它是一个 cstring。【参考方案2】:

主要问题是getline 在两种情况下的行为不同:

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

    如果函数没有提取字符,或者如果 一旦(n-1)个字符有 已经写到s了。

    如果遇到换行符,failbit 未设置,换行符被成功读取并被getline 忽略。

接下来发生的事情更有趣:如果输入流为bad()(即failbitbadbiteofbit 设置为开启,则提取函数(我假设所有这些函数)会立即失败流)。特别是,如果先前的提取操作失败,则所有后续操作也将失败。因此,基本上,如果输入的第一行无法放入您的 phrase 数组中,那么 cin 将变为“坏”并且所有进一步的读取操作都不会执行任何操作。

您可以通过在调用getline 后手动重置failbit 来覆盖该行为,如下所示: 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";

您可以在 *** here 和 there 上阅读更多信息。

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

【讨论】:

老师要cstring在第一个,string在第二个。

以上是关于为啥我的部分代码被跳过而不让我输入输入?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 XmlReader 跳过标签?

为啥scanf不能接收键盘输入,被跳过???改成C++的cin>>后便可以接收并继续下去。全部换成C++可以运行。

fork()生成的子进程中的部分代码被跳过

为什么连续的scanf会被跳过或不执行

为什么连续的scanf会被跳过或不执行

如何在VC中输入字符串