2015-11-18 2 views
0

Я столкнулся с интересной проблемой при игре с входными потоками на C++.Ввод с пробелами - Clobbering Next Input (с использованием cin)

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

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

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

#include <iostream> 
#include <string> 

using namespace std; 

int main() 
{ 
    string myString; 
    int myInt; 

    // I know this will cut off the end of the string 
    cout << "Enter a string with spaces: "; 
    cin >> myString; 
    cout << endl; 

    cout << "Enter an integer: "; 
    cin >> myInt; 
    cout << endl; 

    cout << "String: " << myString << endl; 
    cout << "Int : " << myInt << endl; 

    return 0; 
} 

Выход:

Enter a string with spaces: This is a string 

Enter an integer: 
String: This 
Int : -858993460 

Есть ли способ поймать на эту ошибку так невежественный пользователь не вводит строку с пробелами и разбить всю программу?

+0

Это способ ввода потока. После того, как вы прочитали «Это», остальная часть ввода все еще присутствует во входном буфере. Когда вы пытаетесь прочитать 'myInt', он видит« is », признает, что это не действительное целое число и не может получить значение. Вы можете попробовать 'getline' или' ignore() 'пропустить вход, который вы не хотите. –

+0

Интересно, я никогда не слышал о 'ignore()' раньше. Мне нужно будет изучить это. – tjwrona1992

ответ

0

Чтение с cin не читает целую строку, а затем возвращает ее только часть. Понятно, что он читает «токен», обычно понимаемый как строка, разделенную пробелами, и затем анализирует ее на любой тип, который вы читаете. Он не имеет понятия о «линии». Все входные строки представляют собой один последовательный поток токенов. Поэтому после прочтения строки («This») следующий токен «is», который, разумеется, не может быть проанализирован как int и, следовательно, ошибка.

+0

Вы знаете способ ловушки этой ошибки, поэтому программа не имеет неожиданных результатов, если пользователь ставит слишком много нежелательной информации в поток ввода? – tjwrona1992

+0

Тест 'cin.fail()'. См. Http://en.cppreference.com/w/cpp/io/basic_ios/fail – baruch

Смежные вопросы