为啥我的部分代码被跳过而不让我输入输入?
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 useendl
除非您知道并需要它的副作用
嗯。什么“副作用”?它对我来说效果很好......从来没有问题。
请在询问之前阅读链接
【参考方案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()
(即failbit
、badbit
或eofbit
设置为开启,则提取函数(我假设所有这些函数)会立即失败流)。特别是,如果先前的提取操作失败,则所有后续操作也将失败。因此,基本上,如果输入的第一行无法放入您的 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 风格的字符串与istream
s 一起使用,我建议您改用string
和std::getline
(如Shreevardhan's answer);它会产生更清晰的代码,不会有多余的情况。
【讨论】:
老师要cstring在第一个,string在第二个。以上是关于为啥我的部分代码被跳过而不让我输入输入?的主要内容,如果未能解决你的问题,请参考以下文章