getline (cin, aString) получает вход без другого ввода - PullRequest
6 голосов
/ 23 февраля 2012

Мой код выглядит следующим образом:

string aString;
cin >> aString;
cout << "This is what cin gets:" << aString << endl;
getline(cin, aString);
cout << "This is what getline(cin, <string>) gets:" << aString << endl;

Каждый раз, когда я запускаю его, я даю вводы типа "12", я получаю "12" и "".

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

Я могу понять, когда я введу что-то вроде «12 24», cin получит «12», а getline должен получить остальное.(Также, если можно было бы ответить, пробел между ними рассматривается как конец для cin, так почему же он передается в getline?)

Просто начинаем со строки на C ++, поэтому, пожалуйста, не делайте этогослишком сложно.Спасибо тебе.

Ответы [ 3 ]

12 голосов
/ 23 февраля 2012

Когда вы смешиваете стандартное извлечение потока с getline, иногда getline возвращает пустую строку.Причина этого заключается в том, что если вы читаете ввод с помощью >>, символ новой строки, введенный пользователем, чтобы показать, что они сделаны, не удаляется из потока ввода.Следовательно, когда вы вызываете getline, функция считывает оставшийся символ новой строки и возвращает пустую строку.

Чтобы это исправить, либо последовательно используйте getline для ввода, либо используйте манипулятор потока ws для извлечения дополнительного белогопробел после чтения:

cin >> value >> ws;

Это сожжет новую строку, исправив проблему.

Надеюсь, это поможет!

7 голосов
/ 23 февраля 2012

вот что я получаю:

std::string str;
std::cin >> str;  //hello world
std::cout << str;  //hello

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

std::string str;
std::getline(std::cin, str);  //hello world
std::cout << str;  //hello world

вы получаете полную строку, getline () работает, пока не найдет первый конец строки и не вернет это значение в виде строки.

Тем не менее, при токенизации, если в потоке остались символы (например, \ n), они будут доступны при вызове getline, вам необходимо очистить поток.

std::cin.ignore();
1 голос
/ 24 февраля 2012

"cin >> x" не использует символ новой строки из входного потока, поэтому следующая строка, которую вы получите с помощью getline, будет содержать пустую строку.Одним из способов решения этой проблемы является использование getline для извлечения входных данных построчно и использование stringstream для токенизации каждой строки.После того, как вы извлекли весь ввод из строкового потока, ключевым моментом является вызов stringstream :: clear (), чтобы очистить флаг EOF, установленный для строкового потока, чтобы иметь возможность использовать его позже в коде.

Вотпример:

#include <iostream>
#include <sstream>
#include <string>

using namespace std;

int main() {
    string line;
    stringstream ss;
    getline(cin, line);
    ss << line;
    int x, y, z;
    //extract x, y, z and any overflow characters
    ss >> x >> y >> z >> line;
    ss.clear();
    //reuse ss after clearing the eof flag
    getline(cin, line);
    ss << line;
    //extract new fields, then clear, then reuse
    //...
    return 0;
}

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

...