Bagaimana cara membersihkan buffer cin?


Jawaban:


101

Mungkin:

std::cin.ignore(INT_MAX);

Ini akan membaca dan mengabaikan semuanya sampai EOF. (Anda juga bisa memberikan argumen kedua yang merupakan karakter untuk dibaca sampai (mis:'\n' mengabaikan satu baris).

Juga: Anda mungkin ingin melakukan: std::cin.clear();sebelum ini juga untuk menyetel ulang status streaming.


10
(Lama, saya tahu.) Hapus sebelumnya, jadi streaming dimasukkan ke dalam kondisi baik di mana ia dapat beroperasi pada buffernya.
GManNickG

Terima kasih, GMan! Melakukannya dengan cara yang salah, pertama, dan menghabiskan cukup banyak waktu untuk mencari kesalahan saya.
balu

@GManNickG, baru saja diperbaiki jawabannya.
bwDraco

@DragonLord: Solusi jelas yang seharusnya saya lakukan di belakang, terima kasih. :)
GManNickG

3
Hanya ingin menunjukkan bahwa untuk kasus saya, saya merasa '\ n' diperlukan. Jika tidak, "cin >>" berikutnya tidak berfungsi.
Cardin

114

Saya lebih suka batasan ukuran C ++ daripada versi 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
Lebih penting lagi, nilainya mungkin berbeda! (streamsize tidak harus int)

2
bisakah Anda mengutip sebuah contoh di mana kita perlu mengabaikan sampai akhir file karena jika saya menggunakan cindan menggunakan pernyataan pertama di atas untuk membersihkan cinbuffer, maka itu terus meminta masukan sampai saya masuk EOFdengan menekan ctrl+d?
ajay

@ajay: Tidak. Itu adalah sesuatu yang perlu Anda putuskan. Saya hanya menjelaskan apa yang akan dilakukan di atas.
Martin York

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

Ini adalah satu-satunya hal yang berhasil bagi saya saat membaca dari konsol. Dalam setiap kasus lain itu akan terbaca tanpa batas karena kurangnya \ n, atau sesuatu akan tetap ada di buffer.

EDIT: Saya menemukan bahwa solusi sebelumnya memperburuk keadaan. Namun, yang satu ini berhasil:

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

13

Saya telah menemukan dua solusi untuk ini.

Yang pertama, dan paling sederhana, adalah menggunakan std::getline()misalnya:

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

... yang akan membuang aliran input ketika sampai ke baris baru. Baca lebih lanjut tentang fungsi ini di sini .

Opsi lain yang langsung membuang aliran adalah ini ...

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

Semoga berhasil!


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

Saya lebih memilih:

cin.clear();
fflush(stdin);

Ada contoh di mana cin.ignore tidak memotongnya, tapi saya tidak bisa memikirkannya saat ini. Beberapa waktu yang lalu ketika saya perlu menggunakannya (dengan Mingw).

Namun, fflush (stdin) adalah perilaku tidak terdefinisi menurut standar. fflush () hanya dimaksudkan untuk aliran keluaran. fflush (stdin) sepertinya hanya berfungsi seperti yang diharapkan di Windows (setidaknya dengan kompiler GCC dan MS) sebagai ekstensi ke standar C .

Jadi, jika Anda menggunakannya, kode Anda tidak akan portabel.

Lihat Menggunakan fflush (stdin) .

Selain itu, lihat http://ubuntuforums.org/showpost.php?s=9129c7bd6e5c8fd67eb332126b59b54c&p=452568&postcount=1 untuk alternatif.


9
fflush (stdin); adalah Perilaku Tidak Terdefinisi (dalam bahasa pemrograman C), secara eksplisit dinyatakan di 7.18.5.2/2
Cubbi

1
1 untuk menyediakan kludge yang valid dan berfungsi. Beberapa orang memiliki pekerjaan yang lain memiliki standar.
Mikhail

5
@ Mikhail: Pekerjaan Anda harus mencakup penulisan kode standar yang sesuai. Saya akan memastikan untuk menghindari penggunaan apa pun yang telah Anda tulis di masa mendatang.
Ed S.

4

Solusi (manual) lain yang mungkin adalah

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

Saya tidak bisa menggunakan fflush atau cin.flush () dengan CLion jadi ini berguna.


loop tak terbatas untuk saya.
StarWind0

Ini berfungsi hanya jika ada akhir baris, jika tidak loop tak terbatas
Bobul Mentol

2

Cara termudah:

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

Ini hanya memposisikan penunjuk cin di akhir aliran stdin dan cin.clear () menghapus semua flag kesalahan seperti flag EOF.


1

Berikut ini seharusnya bekerja:

cin.flush();

Pada beberapa sistem, ini tidak tersedia dan Anda dapat menggunakan:

cin.ignore(INT_MAX);

1
mengapa menulis loop secara manual ketika Anda dapat memberitahu abaikan karakter INT_MAX baca sampai mencapai EOF (nilai default dari param kedua).
Evan Teran

Gunnar, mungkin lebih baik mengedit posting Anda untuk mencerminkan ini, untuk berjaga-jaga.
Dana the Sane

1
Sejauh yang saya tahu, flushmetode ini hanya untuk keluaran, dan berhubungan dengan karakter yang sudah tertulis.
Marc van Leeuwen

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

1
#include <stdio_ext.h>

dan kemudian gunakan fungsi

__fpurge(stdin)

0

cin.get() tampaknya memerah secara otomatis cukup aneh (meskipun mungkin tidak disukai, karena ini membingungkan dan mungkin temperamental).


0

Itu berhasil untuk saya. Saya telah menggunakan for loop dengan getline ().

cin.ignore()
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.