в программе на c ++ после нажатия клавиши Enter cin будет кормить все переменные - PullRequest
0 голосов
/ 24 марта 2020

У меня есть программа, которая берет два числа и показывает их на экране.

Однако, когда я нажимаю «ввод» после ввода первого числа, моя программа показывает ответы, прежде чем позволить мне ввести второе число.

Почему это происходит?

int main()
{
    int n1;
    float n2;

    cin>>n1;

    cin>>n2;

    cout<<"int n:"<<n1<<endl<<"float n:"<<n2;

    return 0;
}

Я хочу ввести 0,25 и 35, но когда я пишу 0,25 и нажимаю Enter, неожиданно появляется ответ "int: n: 0 float n: 0,25 "это не позволяет мне писать второе число. Моя ОС - Win10, и эта программа скомпилирована с Dev Cpp

. Она работает, когда обе переменные являются целыми числами.

1 Ответ

2 голосов
/ 24 марта 2020

Нет разницы между cin>>n1; cin>>n2; и cin >> n1 >>n2. Клавиша ввода служит только для синхронизации входного буфера и потокового буфера. cin не вводит данные в каждой строке, он анализирует буфер при наличии доступного объема данных. Если синтаксический анализ не завершен, он ждет. Если анализ не может быть выполнен, он останавливается и бит состояния изменяется. Чтобы продолжить синтаксический анализ, вы должны либо игнорировать, либо очищать содержимое буфера части или всего.

В первой строке было введено что-то неправильное, из-за чего cin до go перешли в состояние bad(). Крайний случай может произойти, если вы запускаете программу через удаленный терминал, может появиться какой-то неправильный символ, например, ^ M, сгенерированный новой строкой из Windows, прервет поток cin на Linux. Это также в том случае, если вы вводите из файла, который был сохранен на другой платформе. На Windows концы строк состоят из двух символов, # 10 и # 13. На linux пары ожидают только # 13 в качестве новой строки и буфера flu sh сигнал, # 10 - неожиданный символ.

Edit (после того, как OP дал информацию о входных данных) :

«0,25» будет проанализировано как «0» и «.25», что соответствует ожидаемому и задокументированному поведению потока. Разбор для n1 прекратился, как только поток встретил символ, который не соответствует шаблону int, который может быть пробелом, концом строки, алфавитом c или пунктуацией. Период считается пунктуацией в этом случае

Затем он пытается получить число с плавающей точкой из потока ввода, и буфер содержит «.25». Это допустимая нотация с плавающей точкой, и ей присваивается значение n2.

Если у вас есть оба значения типа «int», вы не можете получить второе значение с одним и тем же вводом, оно всегда будет 0, потому что cin блокируется в плохом состоянии, т.е. метод его istream::good() возвращает false. Вы должны проверить состояние потока после чтения переменных. Любое дальнейшее форматированное чтение, которое не сможет проанализировать .25, не приведет к продвижению потока после этой точки.

Если вы хотите читать из потока исключительно построчно, вы должны использовать метод istream::getline() чтобы получить строку. Существует также метод get, который может получать содержимое потока, и ignore, который позволяет отбрасывать часть потока.

...