Jak opróżnić bufor Cin?

110

Jak wyczyścić bufor cin w C ++?

Dana the Sane
źródło

Odpowiedzi:

101

Możliwie:

std::cin.ignore(INT_MAX);

To by przeczytało i zignorowało wszystko do EOF. (możesz również podać drugi argument, który jest znakiem do odczytania do (np: '\n'aby zignorować pojedynczą linię).

Ponadto: prawdopodobnie chcesz również wykonać: std::cin.clear();przed tym, aby zresetować stan strumienia.

Evan Teran
źródło
10
(Stare wiem.) Raczej wyczyść wcześniej, więc strumień jest wprowadzany w dobry stan, w którym może działać na swoim buforze.
GManNickG
Dzięki, GMan! Zrobiłem to najpierw w niewłaściwy sposób i spędziłem trochę czasu szukając mojego błędu.
balu
@GManNickG, właśnie naprawiłem odpowiedź.
bwDraco
@DragonLord: Oczywiste rozwiązanie, które powinienem był zrobić z perspektywy czasu, dzięki. :)
GManNickG
3
Chciałem tylko zaznaczyć, że w moim przypadku uważam, że opcja „\ n” jest konieczna. W przeciwnym razie kolejne "cin >>" nie zadziała.
Cardin
114

Wolałbym ograniczenia rozmiaru C ++ od wersji 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')
Martin York
źródło
15
Co ważniejsze, wartości mogą być inne! (rozmiar strumienia nie musi być int)
2
czy mógłbyś zacytować przykład, w którym musimy zignorować do końca pliku, ponieważ jeśli użyję cini użyję pierwszej instrukcji powyżej do opróżnienia cinbufora, to wyświetla monit o wprowadzenie danych, dopóki nie wejdę EOF, naciskając ctrl+d?
ajay
@ajay: Nie. To jest coś, o czym musisz zdecydować. Ja tylko wyjaśniam, co zrobi powyższe.
Martin York,
23
cin.clear();
fflush(stdin);

To była jedyna rzecz, która zadziałała podczas czytania z konsoli. W każdym innym przypadku albo czytałby w nieskończoność z powodu braku \ n, albo coś pozostawało w buforze.

EDYCJA: Dowiedziałem się, że poprzednie rozwiązanie pogorszyło sprawę. TEN jednak działa:

cin.getline(temp, STRLEN);
if (cin.fail()) {
    cin.clear();
    cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
jyggorath
źródło
13

Znalazłem dwa rozwiązania tego problemu.

Pierwszym i najprostszym jest użycie std::getline()na przykład:

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

... to odrzuci strumień wejściowy, gdy dotrze do nowej linii. Przeczytaj więcej o tej funkcji tutaj .

Inną opcją, która bezpośrednio odrzuca strumień, jest to ...

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

Powodzenia!

Ben
źródło
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";
Martin York
źródło
4

Wolę:

cin.clear();
fflush(stdin);

Jest przykład, w którym cin.ignore po prostu tego nie robi, ale w tej chwili nie mogę o tym myśleć. To było jakiś czas temu, kiedy musiałem go użyć (z Mingw).

Jednak fflush (stdin) jest niezdefiniowanym zachowaniem zgodnie ze standardem. fflush () jest przeznaczona tylko dla strumieni wyjściowych. fflush (stdin) tylko wydaje się działać zgodnie z oczekiwaniami na Windows (z GCC i MS kompilatory przynajmniej) jako rozszerzenie standardu C .

Jeśli więc go użyjesz, Twój kod nie będzie przenośny.

Zobacz Używanie fflush (stdin) .

Zobacz także http://ubuntuforums.org/showpost.php?s=9129c7bd6e5c8fd67eb332126b59b54c&p=452568&postcount=1, aby znaleźć alternatywę.

Cień2531
źródło
9
fflush (stdin); to Undefined Behavior (w języku programowania C), wyraźnie określone tak w 7.18.5.2/2
Cubbi,
1
+1 za dostarczenie ważnej, działającej masy. Niektórzy ludzie mają pracę, inni mają standardy.
Michaił
5
@Mikhail: Twoja praca powinna obejmować pisanie kodu zgodnego ze standardami. Postaram się unikać używania w przyszłości wszystkiego, co napisałeś.
Ed S.
4

Innym możliwym (ręcznym) rozwiązaniem jest

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

Nie mogę użyć fflush ani cin.flush () z CLion, więc to się przydało.

Bobul Mentol
źródło
nieskończona pętla dla mnie.
StarWind0
Działa tylko wtedy, gdy istnieje koniec linii, w przeciwnym razie nieskończona pętla
Bobul Mentol
2

Najprostszy sposób:

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

Po prostu umieszcza wskaźnik cin na końcu strumienia stdin, a cin.clear () czyści wszystkie flagi błędów, takie jak flaga EOF.

Chaitanya Vaishampayan
źródło
1

Powinno działać:

cin.flush();

W niektórych systemach nie jest dostępny, a następnie możesz użyć:

cin.ignore(INT_MAX);
Gunnar Steinn
źródło
1
po co ręcznie pisać pętlę, skoro można powiedzieć, że zignoruj ​​odczytane znaki INT_MAX, dopóki nie osiągnie EOF (domyślna wartość drugiego parametru).
Evan Teran
Gunnar, na wszelki wypadek lepiej zmodyfikuj swój post, aby to odzwierciedlić.
Dana the Sane
1
O ile wiem, flushmetoda służy tylko do wyświetlania i dotyczy już zapisanych znaków.
Marc van Leeuwen
cin.flush ():basic_istream<char>' has no member named 'flush'
eric
1
#include <stdio_ext.h>

a następnie użyj funkcji

__fpurge(stdin)
techcomp
źródło
0

cin.get() wydaje się, że spłukuje go automatycznie, dość dziwnie (chociaż prawdopodobnie nie jest to preferowane, ponieważ jest to mylące i prawdopodobnie temperamentne).

GuestPerson001
źródło
0

U mnie to zadziałało. Użyłem pętli for z getline ().

cin.ignore()
Amrit Malla
źródło