Если операторы в цикле do while с окончанием да или нет

Я новичок в кодировании, и я пытаюсь сделать длинный do while цикл с вложенным if заявления, но у меня есть проблемы с получением моего цикла на самом деле цикл.

Вместо того, чтобы получать помощь непосредственно в моем проекте, который имеет очень длинный код, я сделал простую версию, похожую на эту. Это также не зацикливается. Он доберется до конца и спросит пользователя, не хотят ли они повторить попытку, но когда введено "y", он игнорирует операторы if.

#include <iostream>
#include <string>
using namespace std;

int main()
{
    string sodaChoice;
    char answer = 'n';

    do
    {
        cout << "Please choose your favorite soda from the following: Rootbeer, Diet Coke, Coke, Sprite" << "\n";
        getline(cin, sodaChoice);

        if (sodaChoice == "Rootbeer")
        {
            cout << "Me too!" << "\n";
        }
        else if (sodaChoice == "Diet")
        {
            cout << "Not me :(" << "\n";
        }
        else if (sodaChoice == "Coke")
        {
            cout << "It's alright" << "\n";
        }
        else if (sodaChoice == "Sprite")
        {
            cout << "only if I'm sick" << "\n";

        }
        else
        {
            cout << "That was not on the list";
        }
        cout << "would you like to try again?";
        cin >> answer;



    } while (answer == 'y'|| answer == 'Y');




    return 0;
}

Я подумал, что, возможно, мне нужен цикл do в цикле do вокруг операторов if, но тогда я не знал, как это сделать. Любая помощь будет оценена. Я потратил много-много часов, пытаясь понять это.

Я пытался спросить своего учителя, но мой колледж преподает из некоторой общей учебной программы, которую их декан написал на основе ее книги. Он не очень любит помогать или учить.

РЕДАКТИРОВАТЬ: Спасибо всем за ответы! Что касается дублирующего вопроса, я еще не изучил cin.ignore, поэтому я не знал, что он имеет отношение к моей проблеме. Спасибо всем за то, что научили меня!

4 ответа

С

cin >> answer;

вы читаете ровно один символ Проблема в том, что при вводе ответа вы ввели как минимум два символа. Настоящий 'y' или же 'n' плюс клавиша Enter, которая добавляется в качестве новой строки в буфере ввода.

Эта новая строка затем читается следующим getline позвонить как пустая строка.

Есть несколько решений этой проблемы, например, с помощью ignore после прочтения в answer, Или, если вы хотите вводить только одним словом, вы можете использовать форматированный ввод, используя >> за sodaChoice также, так как по умолчанию он пропускает начальные пробелы (как переводы строк).

Существующие ответы верны в том случае, если пользователь ведет себя хорошо и вводит только "y" или "n", а затем перевод строки.

Мы можем добавить немного безопасности с модификацией к вызову.ignore(), попросив его игнорировать все символы вплоть до следующего символа новой строки:

Вам нужно будет добавить этот заголовок в верхней части вашего блока перевода:

#include <limits>

И вам нужно будет добавить эту строку, прежде чем cin >> answer:

// consumes and ignores as many characters as necessary until a newline. 
// The newline is also consumed.
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

Полная программа с тестовыми входами здесь:

http://coliru.stacked-crooked.com/a/996e77559590ad6d

К сожалению, учителя информатики нередко ничего не знают о компьютерных науках. Не беспокойтесь об этом и не позволяйте этому научиться писать программы - это всего лишь признак того, что хорошим программистам платят намного больше, чем хорошим учителям.

Вот несколько полезных справочных материалов: https://en.cppreference.com/w/cpp/io/basic_istream/ignore

Я собираюсь предложить что-то совершенно противоположное другим ответам. Вместо того, чтобы использовать cin.ignore чтобы пропустить лишние символы после того, который вы прочитали, я думаю, что лучше читать все с getline() и забыть о cin >> somevar полностью.

Есть две причины:

  1. Форматированный ввод, который вы получаете с cin >> somevar игнорирует начальные пробелы, включая переводы строки. Если пользователь нажимает Enter в пустой строке, программа ничего не делает, но все же ожидает дальнейшего ввода. Это не то, что ожидает пользователь программы CLI! Обычное ожидание состоит в том, что ввод завершает ввод, и пустой ввод должен либо заставить программу использовать значение по умолчанию, либо жаловаться на неверный ввод. С cin >> somevar Вы тоже не можете.

  2. Форматированный ввод оставляет любые несогласованные входные данные в буфере. В вашем примере чтение одного символа оставляет по крайней мере следующую новую строку, но то же самое происходит с другими видами ввода. Чтение числа (с int i; cin >> i;) оставляет после числа число, ожидающее следующей операции ввода, поэтому ввод 123 abc вернусь 123 и abc появится на следующей операции ввода.

    Основная причина этого заключается в том, что по умолчанию терминал командной строки находится в режиме строки. Программа или библиотечные функции не видят никакой информации от операционной системы до тех пор, пока не будет введена полная строка. (cin.ignore() может конечно помочь вам разобраться с этим, но не с первого пункта.)

С помощью getline() точно соответствует основной механике, позволяет работать с пустыми входами (а также сообщать разницу между нулем и не числом при чтении в int) и автоматически обрабатывает завершающий мусор. Вы должны будете преобразовать прочитанную строку вручную в то, что вам нужно.

В вашем случае вы можете тривиально изменить условие цикла на что-то вроде этого:

string answer;
...
    getline(cin, answer);
} while (answer == "y" || answer == "Y");

Если вам нужен номер, вы можете использовать, например, int num = std::stoi(str),


(В C то же самое происходит при использовании scanf() для пользовательского ввода, и аналогично, лучше использовать fgets() а затем проанализировать строку с sscanf() , который дает те же параметры, но имеет дело с буферизацией строки. Я не слишком знаком с C++, поэтому я не могу сказать, как получить точный эквивалент cin >> somevar с полной строкой, прочитанной getline() .)

Поскольку вы принимаете ввод от пользователя типа char но каждый Enter нажатие клавиши, назначает новую строку (\n) к переменной answer,

Вы можете игнорировать это, добавив строку сразу после строки ввода

cin.ignore();

Вы можете прочитать это для более подробной информации.

Другие вопросы по тегам