【问题标题】:Issue When Clearing cin Buffer After Using cin.getline()使用 cin.getline() 后清除 cin 缓冲区时的问题
【发布时间】: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) 时会少一点。此外,还有诸如 eofbitfailbitbadbit 之类的标志,但这可能还不够。如果您想继续使用此版本的 getline,您应该对 cin.gcount() 感兴趣,以了解读取了多少个字符。
  • 这解决了我的问题 Stefan,谢谢。我做了 if (cin.gcount() > SIZE) 并且涵盖了所有案例以及我遇到问题的案例。

标签: c++ getline


【解决方案1】:

您可以使用istream::gcount() 来确定行中是否还有除'\n' 之外的其他字符。

以下是您需要考虑的情况。

  1. cin.gcount() 的返回值小于SIZE-1。在这种情况下,线路中没有任何内容。您不必担心会忽略该行的其余部分。

  2. cin.gcount() 的返回值为SIZE-1。这可能是由于两种情况。

    1. 用户输入SIZE-2 字符后跟换行符。在这种情况下,线路中没有任何内容。您不必担心会忽略该行的其余部分。

    2. 用户输入SIZE 或更多字符,后跟换行符。在这种情况下,该行中还剩下一些字符。您将需要忽略该行的其余部分。

  3. cin.gcount() 的返回值为SIZE。仅当用户输入SIZE-1 字符后跟换行符时,才会发生这种情况。该行中的所有字符都被读入提供给函数的参数中。换行符被读取并丢弃。您不必担心会忽略该行的其余部分。

在上述情况下,您唯一需要担心忽略该行的其余部分是遇到案例 2.2 时。当cin.gcount() == SIZE-1strlen(words) == SIZE-1 时满足该条件。

void getString(char* words) {
    cout << "Enter your string: ";
    cin.getline(words, SIZE);
    if (cin.gcount() == SIZE-1 && strlen(words) == SIZE-1)
    {
        // There are characters in the stream before the \n.
        cin.clear();
        cin.ignore(numeric_limits<streamsize>::max(), '\n');
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多