Jak opróżnić bufor Cin?


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.


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')

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');
}

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!


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

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ę.


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.


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.


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);

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


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).


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.