Làm cách nào để xả bộ đệm cin?


Câu trả lời:


101

Có khả năng:

std::cin.ignore(INT_MAX);

Điều này sẽ đọc trong và bỏ qua mọi thứ cho đến khi EOF. (bạn cũng có thể cung cấp đối số thứ hai là ký tự sẽ đọc cho đến (ví dụ: '\n'để bỏ qua một dòng).

Ngoài ra: Bạn có thể muốn thực hiện: std::cin.clear();trước cả việc này để đặt lại trạng thái luồng.


10
(Tôi biết rồi.) Rõ ràng trước đây, đúng hơn, vì vậy luồng được đưa vào trạng thái tốt nơi nó có thể hoạt động trên bộ đệm của nó.
GManNickG

Cảm ơn GMan! Đầu tiên, tôi đã làm sai cách, và đã dành khá nhiều thời gian để tìm ra lỗi của mình.
balu

@GManNickG, vừa sửa câu trả lời.
bwDraco

@DragonLord: Giải pháp rõ ràng mà tôi nên thực hiện trong nhận thức muộn màng, cảm ơn. :)
GManNickG

3
Tôi chỉ muốn chỉ ra rằng đối với trường hợp của tôi, tôi thấy '\ n' là cần thiết. Nếu không, "cin >>" tiếp theo không hoạt động.
Cardin

114

Tôi thích các ràng buộc về kích thước C ++ hơn các phiên bản 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
Quan trọng hơn, các giá trị có thể khác nhau! (kích thước luồng không nhất thiết phải là int)

2
bạn có thể vui lòng trích dẫn một ví dụ mà chúng tôi cần bỏ qua ở cuối tệp vì nếu tôi sử dụng cinvà sử dụng câu lệnh đầu tiên ở trên để xóa cinbộ đệm, thì nó sẽ tiếp tục nhắc nhập cho đến khi tôi nhập EOFbằng cách nhấn ctrl+d?
ajay

@ajay: Không. Đó là điều bạn cần phải quyết định. Tôi chỉ đang giải thích những gì ở trên sẽ làm.
Martin York

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

Đây là điều duy nhất hiệu quả với tôi khi đọc từ bảng điều khiển. Trong mọi trường hợp khác, nó sẽ đọc vô thời hạn do thiếu \ n hoặc thứ gì đó sẽ vẫn còn trong bộ đệm.

CHỈNH SỬA: Tôi phát hiện ra rằng giải pháp trước đây làm cho mọi thứ trở nên tồi tệ hơn. Tuy nhiên, cái này hoạt động:

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

13

Tôi đã tìm thấy hai giải pháp cho điều này.

Đầu tiên, và đơn giản nhất, là sử dụng std::getline()ví dụ:

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

... điều đó sẽ loại bỏ luồng đầu vào khi chuyển sang dòng mới. Đọc thêm về chức năng này ở đây .

Một tùy chọn khác hủy trực tiếp luồng là ...

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

Chúc may mắ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

Tôi thích:

cin.clear();
fflush(stdin);

Có một ví dụ mà cin.ignore không cắt nó, nhưng tôi không thể nghĩ ra vào lúc này. Đó là một thời gian trước đây khi tôi cần sử dụng nó (với Mingw).

Tuy nhiên, fflush (stdin) là hành vi không xác định theo tiêu chuẩn. fflush () chỉ dành cho các luồng đầu ra. fflush (stdin) dường như chỉ làm việc như mong đợi trên Windows (với GCC và MS trình biên dịch ít nhất) là một mở rộng của tiêu chuẩn C .

Vì vậy, nếu bạn sử dụng nó, mã của bạn sẽ không di động được.

Xem Sử dụng fflush (stdin) .

Ngoài ra, hãy xem http://ubuntuforums.org/showpost.php?s=9129c7bd6e5c8fd67eb332126b59b54c&p=452568&postcount=1 để có giải pháp thay thế.


9
fflush (stdin); là Hành vi không xác định (bằng ngôn ngữ lập trình C), được nêu rõ ràng như vậy trong 7.18.5.2/2
Cubbi

1
+1 để cung cấp k bùn hợp lệ, hoạt động. Một số người có công việc những người khác có tiêu chuẩn.
Mikhail

5
@Mikhail: Công việc của bạn nên bao gồm việc viết mã tuân thủ tiêu chuẩn. Tôi sẽ đảm bảo tránh sử dụng bất kỳ thứ gì bạn đã viết trong tương lai.
Ed S.

4

Một giải pháp khả thi (thủ công) khác là

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

Tôi không thể sử dụng fflush hoặc cin.flush () với CLion nên điều này rất hữu ích.


vòng lặp vô hạn cho tôi.
StarWind0

Nó chỉ hoạt động nếu có cuối dòng, nếu không thì vòng lặp vô hạn
Bobul Mentol

2

Cách dễ nhất:

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

Nó chỉ định vị con trỏ cin ở cuối luồng stdin và cin.clear () xóa tất cả các cờ lỗi như cờ EOF.


1

Những điều sau sẽ hoạt động:

cin.flush();

Trên một số hệ thống, nó không khả dụng và sau đó bạn có thể sử dụng:

cin.ignore(INT_MAX);

1
tại sao phải viết vòng lặp theo cách thủ công khi bạn có thể cho biết bỏ qua các ký tự INT_MAX đã đọc cho đến khi nó đạt đến EOF (giá trị mặc định của tham số thứ hai).
Evan Teran

Gunnar, tốt hơn là nên chỉnh sửa bài đăng của bạn để phản ánh điều này, đề phòng.
Dana the Sane

1
Theo như tôi có thể nói, flushphương thức này chỉ dành cho đầu ra và xử lý các ký tự đã được viết sẵn.
Marc van Leeuwen

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

1
#include <stdio_ext.h>

và sau đó sử dụng chức năng

__fpurge(stdin)

0

cin.get() dường như tự động tuôn ra một cách kỳ lạ (mặc dù có lẽ không được ưa thích, vì điều này là khó hiểu và có thể là tính khí thất thường).


0

Nó đã làm việc cho tôi. Tôi đã sử dụng vòng lặp for với getline ().

cin.ignore()
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.