Bagaimana cara membersihkan buffer cin?

110

Bagaimana cara menghapus buffer cin di C ++?

Dana the Waras
sumber

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.

Evan Teran
sumber
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')
Martin York
sumber
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');
}
jyggorath.dll
sumber
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!

Ben
sumber
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
sumber
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.

Bayangan2531
sumber
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.

Bobul Mentol
sumber
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.

Chaitanya Vaishampayan
sumber
1

Berikut ini seharusnya bekerja:

cin.flush();

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

cin.ignore(INT_MAX);
Gunnar Steinn
sumber
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)
techcomp
sumber
0

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

GuestPerson001
sumber
0

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

cin.ignore()
Amrit Malla
sumber