Реальное решение проблемы «cin» и «getline»

Как мне избавиться от начальных символов ' ' и '\n', если я не уверен, что получу cin перед getline?

Пример:

int a;
char s[1001];
if(rand() == 1){
    cin >> a;
}

cin.getline(s);

Если я поставлю cin.ignore() перед getline, я могу потерять первый символ строки, так что мой единственный вариант - поместить его после каждого использования 'cin >>' ? Потому что это не очень эффективный способ сделать это, когда вы работаете над большим проектом.

Есть ли лучший способ, чем этот:

int a;
string s;

if(rand() == 1){
    cin >> a;
}

do getline(cin, s); while(s == "");

person lub094    schedule 06.05.2014    source источник
comment
Не уверен, не видя вашего точного ввода, но может быть это помогает and-how-can-i-fi" title="почему не удается прочитать поля записи структуры из stdistream и как я могу это сделать">stackoverflow.com/questions/23047052/   -  person πάντα ῥεῖ    schedule 06.05.2014
comment
Не смешивайте >> и getline. Просто всегда используйте getline. В нынешнем виде ваш код все равно не работает, поскольку вы не проверяете, успешно ли выполнено cin >> a.   -  person Kerrek SB    schedule 06.05.2014


Ответы (2)


Так:

std::string line, maybe_an_int;

if (rand() == 1)
{
    if (!(std::getline(std::cin, maybe_an_int))
    {
        std::exit(EXIT_FAILURE);
    }
}

if (!(std::getline(std::cin, line))
{
    std::exit(EXIT_FAILURE);
}

int a = std::stoi(maybe_an_int);    // this may throw an exception

Вы можете разобрать строку maybe_an_int несколькими способами. Вы также можете использовать std::strtol или строковый поток (при тех же условиях, что и первый блок if):

    std::istringstream iss(maybe_an_int);
    int a;
    if (!(iss >> a >> std::ws) || iss.get() != EOF)
    {
        std::exit(EXIT_FAILURE);
    }

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

person Kerrek SB    schedule 06.05.2014

Как символ пробела, так и символ новой строки классифицируются как пробел стандартными потоками IOStream. Если вы смешиваете форматированный ввод-вывод с неформатированным вводом-выводом и вам нужно очистить поток от остаточных пробелов, используйте std::ws манипулятор:

if (std::getline(std::cin >> std::ws, s) {

}
person 0x499602D2    schedule 06.05.2014