Как очистить буфер cin?


Ответы:


101

Возможно:

std::cin.ignore(INT_MAX);

Это будет читать и игнорировать все, пока EOF. (вы также можете указать второй аргумент, который является символом, который нужно читать до тех пор, пока (например, '\n'игнорировать одну строку).

Также: вы, вероятно, захотите: std::cin.clear(); перед этим, чтобы сбросить состояние потока.


10
(Старый, я знаю.) Скорее очистить раньше, чтобы поток переводился в хорошее состояние, когда он мог работать со своим буфером.
GManNickG 03

Спасибо, мастер! Сначала поступил неправильно и довольно долго искал свою ошибку.
balu

@GManNickG, только что исправил ответ.
bwDraco

@DragonLord: Очевидное решение, которое я должен был сделать задним числом, спасибо. :)
GManNickG

3
Просто хотел указать, что в моем случае я считаю необходимым '\ n'. В противном случае последующее "cin >>" не сработает.
Cardin

114

Я бы предпочел ограничения размера C ++ по версиям C:

// Ignore to the end of file
cin.ignore(std::numeric_limits<std::streamsize>::max())

// Ignore to the end of line
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n')

15
Что еще более важно, значения могут быть разными! (размер потока не обязательно должен быть int)

2
Не могли бы вы привести пример, в котором нам нужно игнорировать до конца файла, потому что, если я использую cinи использую первый оператор выше для очистки cinбуфера, он продолжает запрашивать ввод, пока я не войду EOFнажатием ctrl+d?
Аджай

@ajay: Нет. Это то, что тебе нужно решить. Я просто объясняю, что будет делать вышеупомянутое.
Мартин Йорк

23
cin.clear();
fflush(stdin);

Это единственное, что у меня сработало при чтении с консоли. В любом другом случае он либо будет читать бесконечно из-за отсутствия \ n, либо что-то останется в буфере.

РЕДАКТИРОВАТЬ: Я обнаружил, что предыдущее решение ухудшило ситуацию. ЭТО, однако, работает:

cin.getline(temp, STRLEN);
if (cin.fail()) {
    cin.clear();
    cin.ignore(numeric_limits<streamsize>::max(), '\n');
}

13

Я нашел два решения этой проблемы.

Первый и самый простой - использовать, std::getline()например:

std::getline(std::cin, yourString);

... который отбрасывает входной поток, когда он переходит на новую строку. Подробнее об этой функции здесь .

Другой вариант, который напрямую отбрасывает поток, - это ...

#include <limits>
// Possibly some other code here
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');

Удачи!


9
int i;
  cout << "Please enter an integer value: ";

  // cin >> i; leaves '\n' among possible other junk in the buffer. 
  // '\n' also happens to be the default delim character for getline() below.
  cin >> i; 
  if (cin.fail()) 
  {
    cout << "\ncin failed - substituting: i=1;\n\n";
    i = 1;
  }
  cin.clear(); cin.ignore(INT_MAX,'\n'); 

  cout << "The value you entered is: " << i << " and its double is " << i*2 << ".\n\n";

  string myString;
  cout << "What's your full name? (spaces inclded) \n";
  getline (cin, myString);
  cout << "\nHello '" << myString << "'.\n\n\n";


4

Я предпочитаю:

cin.clear();
fflush(stdin);

Есть пример, когда cin.ignore просто не сокращает его, но я не могу об этом сейчас думать. Это было некоторое время назад, когда мне нужно было использовать его (с Mingw).

Однако fflush (stdin) - это неопределенное поведение согласно стандарту. fflush () предназначен только для выходных потоков. fflush (STDIN) только , кажется, работает , как ожидалось в ОС Windows (с GCC и MS компиляторы по крайней мере) в качестве расширения стандарта C .

Итак, если вы его используете, ваш код не будет переносимым.

См. Использование fflush (stdin) .

Также см. Http://ubuntuforums.org/showpost.php?s=9129c7bd6e5c8fd67eb332126b59b54c&p=452568&postcount=1 для альтернативы.


9
fflush (стандартный ввод); является Undefined Behavior (на языке программирования C), явно заявленное в 7.18.5.2/2
Cubbi

1
+1 за поставку действующего рабочего кладжа. У одних есть работа, у других есть стандарты.
Михаил

5
@Mikhail: Ваша работа должна включать написание стандартного кода. Я буду стараться избегать использования всего, что вы написали в будущем.
Эд С.

4

Другое возможное (ручное) решение:

cin.clear();
while (cin.get() != '\n') 
{
    continue;
}

Я не могу использовать fflush или cin.flush () с CLion, так что это пригодилось.


бесконечный цикл для меня.
StarWind0

Он работает, только если есть конец строки, иначе бесконечный цикл
Бобул Ментол

2

Самый простой способ:

cin.seekg(0,ios::end);
cin.clear();

Он просто помещает указатель cin в конец потока stdin, а cin.clear () очищает все флаги ошибок, такие как флаг EOF.


1

Следующее должно работать:

cin.flush();

В некоторых системах это недоступно, и тогда вы можете использовать:

cin.ignore(INT_MAX);

1
зачем вручную писать цикл, когда вы можете указать игнорировать прочитанные символы INT_MAX, пока он не достигнет EOF (значение по умолчанию для второго параметра).
Эван Теран

Гуннар, может быть, лучше отредактировать свой пост, чтобы отразить это, на всякий случай.
Dana the Sane

1
Насколько я могу судить, flushметод предназначен только для вывода и имеет дело с уже написанными символами.
Марк ван Левен,

cin.flush ():basic_istream<char>' has no member named 'flush'
eric


0

cin.get() кажется, как ни странно, автоматически смывает его (хотя, вероятно, не рекомендуется, поскольку это сбивает с толку и, вероятно, темпераментно).


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.