Ты думаешь об этом неправильно. Вы каждый раз думаете логически, когда используются cin
или getline
. Ex. Сначала попросите номер, затем попросите имя. Это неверный способ думать о cin
. Таким образом, вы сталкиваетесь с условием гонки, потому что считаете, что поток очищается каждый раз, когда вы запрашиваете ввод.
Если вы пишете свою программу исключительно для ввода, вы обнаружите проблему:
void main(void)
{
double num;
string mystr;
cin >> num;
getline(cin, mystr);
cout << "num=" << num << ",mystr=\'" << mystr << "\'" << endl;
}
В приведенном выше примере вы думаете: «Сначала получите номер». Поэтому введите 123
нажмите enter, и ваш выход будет num=123,mystr=''
. Почему это? Это потому, что в потоке вы 123\n
, а 123
анализируется в переменной num
, а \n
все еще находится в потоке. Чтение документа для функции getline
по умолчанию будет выглядеть в istream
до тех пор, пока не встретится \n
. В этом примере, поскольку \n
находится в потоке, похоже, что он «пропустил» его, но он работал должным образом.
Для выполнения вышеизложенного вам нужно будет ввести 123Hello World
, который будет правильно выводить num=123,mystr='Hello World'
. Это, или вы положили cin.ignore
между cin
и getline
, чтобы он перешел на логические шаги, которые вы ожидаете.
Вот почему вам нужна команда ignore
. Потому что вы думаете об этом в логических шагах, а не в форме потока, чтобы вы столкнулись с состоянием гонки.
Возьмите другой пример кода, который обычно встречается в школах:
void main(void)
{
int age;
string firstName;
string lastName;
cout << "First name: ";
cin >> firstName;
cout << "Last name: ";
cin >> lastName;
cout << "Age: ";
cin >> age;
cout << "Hello " << firstName << " " << lastName << "! You are " << age << " years old!" << endl;
}
Вышеизложенное представляется логичным шагом. Сначала спросите имя, фамилию, возраст. Поэтому, если вы ввели John
, введите Doe
, затем введите 19
, приложение выполнит каждый логический шаг. Если вы думаете об этом в «потоках», вы можете просто ввести John Doe 19
в вопрос «Имя:», и он будет работать так же, и, похоже, пропустит оставшиеся вопросы. Для того, чтобы выше работали логическими шагами, вам понадобится ignore
оставшийся поток для каждого логического разрыва в вопросах.
Не забудьте подумать о вводе вашей программы, поскольку она читает из «потока», а не в логических шагах. Каждый раз, когда вы вызываете cin
, он считывается из потока. Это создает довольно ошибочное приложение, если пользователь вводит неверный ввод. Например, если вы ввели символ, где ожидается cin >> double
, приложение будет обрабатывать довольно (казалось бы) странный вывод.