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

console not returning expected number of characters in cin buffer

我正在创建 "Bull Cow Game" 的控制台版本。在游戏中,用户有一定次数的尝试来猜测秘密词是什么。每次他们猜中,程序 returns 他们猜对的 "Bulls" 和 "Cows" 的数目。用户在正确位置猜对的每个字符都会得到一个 "Bull",而他们猜对但位置不对的每个字符都会得到一个 "Cow"。

我的问题出在我的 getGuess() 函数中。在 do-while 循环中,如果用户输入的字符数不是 "answer" 中的字符数,则程序应该循环。当我 运行 我的程序时,我得到了一些意想不到且令人困惑的结果:

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

2) 如果我从 之前的 猜测中更改我猜测的字符数,程序会告诉我 cin.gcount() 是 cin.gcount() 在 previous 猜测之后,而不是在当前猜测之后。这也是一个不受欢迎的结果,因为如果用户决定输入正确的字符数,程序将不会接受用户的猜测是有效的。

我很困惑为什么会这样,因为 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)gcount只告诉你无格式输入操作后读了多少个字符cin >> guess不是无格式输入操作。

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

你的代码太坑爹了,别想花哨的I/O操作了,直截了当。只需使用 getline 将一行字符读入字符串,然后检查输入的字符是否符合您的预期。例如删除该字符串开头和结尾的空格,然后检查内部空格,最后检查字符串是否是您需要的长度。