控制台未在cin缓冲区中返回预期的字符数

时间:2019-03-09 06:38:05

标签: c++ buffer cin

我正在创建“牛牛游戏”的控制台版本。在游戏中,用户有一定次数的尝试来猜测秘密单词是什么。他们每次猜测时,程序都会返回他们正确猜测的“牛”和“牛”数。用户为在正确位置猜到的每个字符获得一个“牛”,并为他们正确猜中但不在正确位置的每个字符得到一个“牛”。

我的问题出在我的getGuess()函数中。在do-while循环中,如果用户在“答案”中输入了除字符数以外的其他任何内容,则该程序应该循环。当我运行程序时,我得到一些意外和令人困惑的结果:

1)不管我为 first “猜测”输入什么,程序都会告诉我cin的gcount()在setw()之后为0或1个字符。我可以输入50个字符或2个字符,程序将输出相同的结果。如果gcount为1,则这算作分配的猜测之一,这是不希望的结果。如果cin.gcount()为0,则程序不会正确地将猜测视为有效,但是我仍然对cin.gcount()为何为0感到困惑。

2)如果我更改了上一个猜测中的字符数,程序将告诉我cin.gcount()等于< strong>上一个猜测,而不是当前猜测之后。这也是不希望的结果,因为如果用户决定输入正确的字符数,则程序将不会接受用户的猜测为有效。

我对为什么会这样感到困惑,因为不是cin.ignore()应该转储setw()不接受的所有无关字符吗?为什么cin缓冲区中的字符数会从一个猜测转移到另一个猜测?

这是有问题的功能:

string getGuess()
{
    string guess = "";

    const int MAX_LENGTH = 4; 

    /*ensures that "guess" is the same length as answer. This
    will make it so that the program avoids comparing "guess"
    to "answer" if "guess" has more characters than "answer".
    This do-while loop also ensures that a user can't overflow
    the cin buffer by theoretically inputting more characters
    than the buffer could contain*/

    bool endLoop = false; 

    do {
        cout << "Enter a word containing exactly " << MAX_LENGTH << " characters: ";

        cin >> setw(MAX_LENGTH) >> guess;

        cout << "cin.gcount() after setw(): " << cin.gcount() << " characters" << endl;

        /*ensures that the only character in the cin is '\n'. Otherwise
        do-while loop continues*/
        if (cin.gcount() != 1)
        {
            cout << "Invalid number of characters. Please input exactly " << MAX_LENGTH 
<< " characters" << endl;
        }
        else
        {
        endLoop = true; 
        }

        cin.ignore(numeric_limits<streamsize>::max(), '\n');

        cout << "cin.gcount() after cin.ignore(): " 
<< cin.gcount() << " characters" << endl;

        cout << "guess: " << guess << endl;

        cout << endl; 

       } while ( endLoop == false );


    cout << endl;


    return guess; 
}

注意:这是使用Microsoft Visual C ++,ISO标准c ++ 17编译的。

1 个答案:

答案 0 :(得分:1)

我认为一些误解

1)gcount仅告诉您未格式化的输入操作后已读取多少个字符,cin >> guess不是未格式化的输入操作。

2)输入setw不会限制读取的字符数。如果读取的字符数少于指定的宽度,则会填充输入以使其等于给定的宽度,但不会停止读取更多的字符。

您的代码太棘手,忘了花哨的I / O操作,以简单的方式进行操作。只需使用getline将一行字符读入字符串,然后检查输入的字符是否符合您的期望。例如,删除该字符串开头和结尾的空格,然后检查内部空格,最后检查该字符串是否为您所需的长度。