консоль не возвращает ожидаемое количество символов в буфере Cin - PullRequest
0 голосов
/ 09 марта 2019

Я создаю консольную версию "Bull Cow Game". В игре пользователь имеет определенное количество попыток угадать, что такое секретное слово. Каждый раз, когда они догадываются, программа возвращает количество «быков» и «коров», которые они правильно угадали. Пользователь получает «Быка» за каждого персонажа, которого он угадывает в нужном месте, и «Корову» за каждого персонажа, которого он угадывает правильно, но не в нужном месте.

Моя проблема в моей функции getGuess (). В цикле do-while программа должна зацикливаться, если пользователь вводит что-либо, кроме количества символов в «ответе». Когда я запускаю свою программу, я получаю неожиданные и запутанные результаты:

1) Независимо от того, что я ввожу для first"предположения", программа сообщает мне, что gcount () cin равен 0 или 1 символу после setw (). Я мог бы ввести 50 символов или 2, и программа выдаст тот же результат. Если gcount равен 1, то это считается одним из выделенных предположений, что является нежелательным результатом. Если cin.gcount () равен 0, программа правильно не считает предположение действительным, но я все еще не понимаю, почему cin.gcount () вообще равен 0.

2) Если я изменю количество символов в моем предположении по сравнению с предыдущим предположением, программа сообщит мне, что cin.gcount () - это то, что cin.gcount () было после предыдущая догадка вместо текущей догадки. Это также является нежелательным результатом, поскольку, если пользователь решит ввести правильное количество символов, программа не примет правильное предположение пользователя.

Меня смущает, почему это происходит, поскольку 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 Ответ

1 голос
/ 09 марта 2019

Несколько недоразумений, я думаю,

1) gcount только говорит вам, сколько символов было прочитано после неформатированной операции ввода , cin >> guess ненеформатированная операция ввода.

2) setw на вводе не ограничивает количество прочитанных символов.Если считываются символы меньше указанной ширины, то ввод дополняется, чтобы сделать его равным заданной ширине, но он не останавливает чтение большего количества символов.

Ваш код слишком сложен, забудьте о сложном вводе / выводеоперации, делайте это простым способом.Просто прочитайте строку символов в строку, используя getline, и убедитесь, что введенные символы соответствуют вашим ожиданиям.Например, удалите пробелы в начале и конце этой строки, затем проверьте наличие внутренних пробелов и, наконец, проверьте, соответствует ли строка нужной вам длине.

...