Як відмити буфер cin?


Відповіді:


101

Можливо:

std::cin.ignore(INT_MAX);

Це буде читати і ігнорувати все, поки EOF. (Ви можете також надати другий аргумент, який є символом, який слід прочитати до (наприклад: '\n'ігнорувати один рядок).

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


10
(Старий я знаю.) Очистити раніше, швидше, тому потік буде приведений у хороший стан, де він може працювати на своєму буфері.
GManNickG

Спасибі, GMan! По-перше, це зробив неправильно, і витратив досить багато часу на пошуки моєї помилки.
balu

@GManNickG, щойно зафіксував відповідь.
bwDraco

@DragonLord: Очевидне рішення, яке я мав би зробити заздалегідь, дякую. :)
GManNickG

3
Просто хотів зазначити, що для мого випадку я вважаю необхідним '\ n'. Інакше подальший "cin >>" не працює.
Кардін

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
Що ще важливіше, значення можуть бути різними! (streamsize не повинен бути int)

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

@ajay: Ні. Це потрібно вирішити. Я просто пояснюю, що буде робити вищезазначене.
Мартін Йорк

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

Це було єдине, що працювало для мене при читанні з консолі. У будь-якому іншому випадку він або читатиметься нескінченно через відсутність \ n, або щось залишатиметься в буфері.

EDIT: Я дізнався, що попереднє рішення погіршило ситуацію. Це, однак, працює:

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 (стдін); є Невизначена поведінка (мовою програмування на С), прямо вказана в 7.18.5.2/2
Cubbi

1
+1 для надання дійсної, робочої каламути. Деякі люди мають роботу, інші мають стандарти.
Михайло

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

4

Ще одне можливе (вручну) рішення

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

Я не можу використовувати fflush або cin.flush () разом із CLion, тому це стане в нагоді.


нескінченна петля для мене.
StarWind0

Він працює лише за наявності кінця рядка, інакше нескінченна петля
Bobul Mentol

2

Найпростіший спосіб:

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

Він просто розміщує покажчик cin у кінці потоку stdin, а cin.clear () видаляє всі прапор помилок, наприклад прапор EOF.


1

Слід працювати:

cin.flush();

У деяких системах це недоступно, і тоді ви можете використовувати:

cin.ignore(INT_MAX);

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

Гуннар, можливо, краще відредагувати свою публікацію, щоб відобразити це, про всяк випадок.
Дана Сане

1
Наскільки я можу сказати, flushметод призначений лише для виведення даних і стосується вже написаних символів.
Марк ван Левен

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

1
#include <stdio_ext.h>

а потім скористайтеся функцією

__fpurge(stdin)

0

cin.get() Здається, це автоматично змиває його досить дивно (хоча, мабуть, не бажано, оскільки це заплутано і, ймовірно, темпераментно).


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.