【发布时间】:2018-12-15 10:29:06
【问题描述】:
我正在使用 getline(cin.getline() 之一)从 cin 获取字符串并发现特殊情况的问题。如果用户输入的字符多于 streamsize 参数(在本例中为 50),则 cin 缓冲区会保存它们并将它们放入下一个 cin 调用中。如果我使用 cin.clear() 和 cin.ignore() 并且用户输入的字符少于 streamsize 参数,那么程序会等待用户再次按 enter 才能继续。所以我使用 strlen 检查字符串的大小,如果字符串有 50 个字符,则仅使用 cin.clear() 和 cin.ignore() 。这会删除用户在第 49 个字符之后输入的额外字符。问题是当用户输入正好 49 个字符时,缓冲区中没有多余的字符可以被 cin.clear() 和 cin.ignore() 调用切断,因此程序将等待用户输入再按回车键。
几个问题:
1) 是否有一个标志我可以检查缓冲区中是否有字符,以便只有当这个标志为真时我才能清除()和忽略()?
2) 有没有其他方法可以调用相同的 getline 函数来截断 streamsize 参数后的所有字符?
这是我的代码:
#include <iostream>
#include <cstring>
using namespace std;
#define SIZE 50
void getString(char*);
int main() {
char words[SIZE];
getString(words);
return 0;
}
void getString(char* words) {
cout << "Enter your string: ";
cin.getline(words, SIZE);
if (strlen(words) == SIZE - 1) {
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
}
可能导致问题的 49 个字符输入示例:
abcdefghijklmnopqrstuvwxysabcdefghijklmnopqrstuvw
删除或添加一个字母,查看程序的正常性能。
【问题讨论】:
-
FWIW,如果你使用
std::string而不是 c 字符串,你可以只使用getline(cin, name_of_string);并获得所有输入。恕我直言,这是你应该走的路。如果字符串需要小于某个大小,您可以轻松检查字符串的大小,如果它太大,则要求新的输入。 -
谢谢 NathanOliver,这对有同样问题的人来说会很好,但我在这里只能使用 cstring(否则会使用 std::string 来处理类似问题)
-
我看到很多人在使用这个版本的 getline 时遇到了困难。当他们开始使用
getline(cin, words)时会少一点。此外,还有诸如 eofbit、failbit、badbit 之类的标志,但这可能还不够。如果您想继续使用此版本的 getline,您应该对cin.gcount()感兴趣,以了解读取了多少个字符。 -
这解决了我的问题 Stefan,谢谢。我做了 if (cin.gcount() > SIZE) 并且涵盖了所有案例以及我遇到问题的案例。