Вот код:
string str;
cin>>str;
cout<<"first input:"<<str<<endl;
getline(cin, str);
cout<<"line input:"<<str<<endl;
Результат состоит в том, что getline никогда не приостанавливаются для ввода данных пользователем, поэтому второй вывод всегда пуст.
После проведения некоторого времени на нем я понял после первого вызова "cin>> ул.", кажется, что '\n' все еще хранится в cin (использующий cin.peek () для проверки), который сразу заканчивает getline. Решение будет добавлять еще одну строку между первым использованием и вторым: cin.ignore(numeric_limits::max(), '\n');
Однако я все еще не понимаю, почему '\n' оставлен там после первого вызова? Что делает istream& оператор>>, действительно делают?
Хорошая запись, объясняющая некоторые причины, по которым вы столкнулись с этой проблемой, в первую очередь из-за поведения типов входных данных и того, что вы их смешиваете
\ n
остается во входном потоке в соответствии с тем, как оператор >>
определен для std :: string
. std :: string
заполняется символами из входного потока до тех пор, пока не будет найден пробельный символ (в данном случае \ n
), после чего заполнение прекращается и пробел теперь следующий символ во входном потоке.
Вы также можете удалить \ n
, вызвав cin.get ()
сразу после cin >> str
. Однако есть много-много разных способов снять шкуру с этой конкретной кошки ввода-вывода. (Может быть, это хороший вопрос сам по себе?)
Как говорили другие, проблема заключается в том, что новая строка остается после первого извлечения. Одно из моих решений - отбросить все левые символы в потоке:
std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
По умолчанию оператор вставки потока читает, пока не видит пробел. Ваш первый вызов не возвращается, пока не увидит пробел, табуляцию, новую строку и т. Д. Затем необходимо использовать следующий символ, чтобы вы могли перейти к следующему.
Я вообще рекомендую делать только линейно-ориентированный ввод из std::cin. Таким образом, ваш код может выглядеть примерно так:
string str;
int val;
// Read an entire line and parse an integer from it
{
string line;
getline(cin, line);
istringstream iss(line);
iss >> val;
}
cout<<"first input:"<<val<<endl;
getline(cin, str);
cout<<"line input:"<<str<<endl;
Не забудьте добавить проверку ошибок.
Подход getline-only позволяет избежать необходимости думать о буферизации ввода по строкам, об очистке ввода и т.д. Если вы напрямую читаете что-то с помощью >>, ввод не прерывается, если пользователь нажимает enter вместо ввода требуемого, а продолжается до тех пор, пока не будет введена лексема (такое поведение обычно нежелательно).