使用cin.getline()后清除cin缓冲区时的问题

时间:2018-07-06 19:41:07

标签: c++ getline

我正在使用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()调用截断,因此程序将坐下来等待用户请按Enter键。

几个问题:

1)是否有一个标志可以检查缓冲区中是否有字符,以便仅当此标志为true时才可以清除()和ignore()?

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

擦除或添加一个字母以查看程序的正常性能。

1 个答案:

答案 0 :(得分: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');
    }
}