【问题标题】: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 除非您知道并需要它的副作用
  • 嗯。什么“副作用”?它对我来说效果很好......从来没有问题。
  • 请在询问之前阅读链接

标签: c++ string c-strings


【解决方案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 在两种情况下的行为不同:

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

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

  2. 如果遇到换行符,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";
}

您可以在 StackOverflow herethere 上阅读更多信息。

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

【讨论】:

  • 老师要cstring在第一个,string在第二个。
猜你喜欢
  • 1970-01-01
  • 2020-06-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-14
  • 1970-01-01
相关资源
最近更新 更多