istream :: ignore и getline () путаница - PullRequest
0 голосов
/ 12 ноября 2011

Я помогаю кому-то с вводом C ++, хотя сам C ++ не знаю.Вот краткий пример:

#include <iostream>
#include <string>

using namespace std;

int main() {
    int i;
    string s;

    cout << "enter i:\n";
    cin >> i;
    cout << "enter s:\n";
    getline(cin, s);
    //cin.ignore(100, '\n');
    cout << "i: " << i << ", s: " << s << "\n";
}

Как и ожидалось, вызов getline() не будет запрашивать ввод у пользователя, поскольку он просто проглотит завершающий \n после вызова cin >> i и сразу же вернется.Что я нахожу странным, так это то, что если вы раскомментируете вызов cin.ignore(), вызов getline() будет запрашивать ввод у пользователя (даже если в s ничего не будет сохранено).Может кто-нибудь объяснить, почему?На мой взгляд, данная строка вообще не должна менять поведение.

Ответы [ 3 ]

1 голос
/ 12 ноября 2011

Ну нет.Это не тот случай, когда «getline() предложит пользователю ввести данные».Очевидно, что оператор ignore приходит после getline() one.

В результате получается, что оператор ignore() просто блокируется до тех пор, пока не выполнит свою задачу, т.е. сожрет 100 символов илиНовая строка, в зависимости от того, что наступит раньше (но не забывайте о буферизации ввода).

В общем, хотя и не напрямую, совет: не смешивайте извлечение токенов (>>) и getline(), точноэта проблема, касающаяся новых строк.Намного лучше придерживаться одной вещи;желательно чтение строки, чтобы вы могли справиться с ошибками и повторить подсказку.Также учитывайте любую неконтролируемую операцию чтения (>>, getline() или istream::read()) как программную ошибку;все они должны быть условными.

1 голос
/ 12 ноября 2011

Это не getline вызов, ожидающий ввода, а ignore, ожидающий игнорирования.

Поставьте ignore перед getline.

1 голос
/ 12 ноября 2011

Мне показалось странным, что если вы раскомментируете вызов cin.ignore (), Вызов getline () предложит пользователю ввести

Нет, не будет. Это оператор игнорирования, который подсказывает пользователю. Как вы понимаете, он делает то же самое, что и getline, за исключением того, что он читает только до 100 символов и просто выбрасывает их.

...