ฉันจะล้างซินบัฟเฟอร์ได้อย่างไร?


คำตอบ:


101

อาจเป็นไปได้:

std::cin.ignore(INT_MAX);

EOFนี้จะอ่านและไม่สนใจทุกอย่างจนกว่า (คุณยังสามารถระบุอาร์กิวเมนต์ที่สองซึ่งเป็นอักขระที่จะอ่านจนถึง (เช่น: '\n'เพื่อละเว้นบรรทัดเดียว)

นอกจากนี้คุณอาจต้องการทำ a: std::cin.clear();ก่อนหน้านี้ด้วยเพื่อรีเซ็ตสถานะสตรีม


10
(เก่าฉันรู้) ก่อนหน้านี้ค่อนข้างชัดเจนดังนั้นสตรีมจึงอยู่ในสถานะที่ดีที่สามารถทำงานบนบัฟเฟอร์ได้
GManNickG

ขอบคุณ GMan! ทำผิดวิธีก่อนและใช้เวลาพอสมควรในการค้นหาความผิดพลาดของฉัน
Balu

@GManNickG เพิ่งแก้ไขคำตอบ
bwDraco

@DragonLord: วิธีแก้ปัญหาที่ชัดเจนฉันควรทำในการมองย้อนกลับไปขอบคุณ :)
GManNickG

3
แค่อยากจะชี้ให้เห็นว่าสำหรับกรณีของฉันฉันพบว่า '\ n' จำเป็น มิฉะนั้น "cin >>" ที่ตามมาจะไม่ทำงาน
Cardin

114

ฉันต้องการข้อ จำกัด ขนาด C ++ มากกว่าเวอร์ชัน 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
ที่สำคัญค่าอาจแตกต่างกัน! (streamize ไม่จำเป็นต้องเป็น int)

2
คุณช่วยยกตัวอย่างที่เราต้องเพิกเฉยต่อท้ายไฟล์ได้ไหมเพราะถ้าฉันใช้cinและใช้คำสั่งแรกด้านบนเพื่อล้างcinบัฟเฟอร์มันจะแจ้งให้ป้อนข้อมูลจนกว่าฉันจะเข้าEOFโดยกดctrl+d?
ajay

@ajay: ไม่นั่นคือสิ่งที่คุณต้องตัดสินใจ ฉันแค่อธิบายว่าข้างต้นจะทำอะไร
Martin York

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

นี่เป็นสิ่งเดียวที่ใช้ได้ผลสำหรับฉันเมื่ออ่านจากคอนโซล ในทุกกรณีมันอาจอ่านไปเรื่อย ๆ เนื่องจากไม่มี \ n หรือบางสิ่งบางอย่างจะยังคงอยู่ในบัฟเฟอร์

แก้ไข: ฉันพบว่าวิธีแก้ปัญหาก่อนหน้านี้ทำให้สิ่งต่างๆแย่ลง อย่างไรก็ตามสิ่งนี้ใช้งานได้:

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

13

ฉันพบวิธีแก้ปัญหาสองวิธีนี้แล้ว

อย่างแรกและง่ายที่สุดคือการใช้ std::getline()ตัวอย่าง:

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

... ซึ่งจะทิ้งสตรีมอินพุตเมื่อเข้าสู่บรรทัดใหม่ อ่านเพิ่มเติมเกี่ยวกับฟังก์ชันนี้ที่นี่

อีกทางเลือกหนึ่งที่ตัดกระแสโดยตรงคือ ...

#include <limits>
// Possibly some other code here
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\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

ฉันชอบ:

cin.clear();
fflush(stdin);

มีตัวอย่างที่ cin.ignore ไม่ได้ตัด แต่ตอนนี้ฉันคิดไม่ออก เมื่อก่อนฉันจำเป็นต้องใช้มัน (กับ Mingw)

อย่างไรก็ตาม fflush (stdin) เป็นพฤติกรรมที่ไม่ได้กำหนดตามมาตรฐาน fflush () มีไว้สำหรับเอาต์พุตสตรีมเท่านั้น fflush (stdin) ดูเหมือนจะทำงานได้ตามที่คาดไว้บน Windows เท่านั้น (อย่างน้อยก็มีคอมไพเลอร์ GCC และ MS) เป็นส่วนขยายของมาตรฐาน Cเป็นส่วนขยายมาตรฐานซี

ดังนั้นหากคุณใช้รหัสของคุณจะไม่สามารถพกพาได้

ดูการใช้ fflush (stdin)

นอกจากนี้โปรดดูhttp://ubuntuforums.org/showpost.php?s=9129c7bd6e5c8fd67eb332126b59b54c&p=452568&postcount=1สำหรับทางเลือกอื่น


9
ฟลัช (stdin); เป็นพฤติกรรมที่ไม่ได้กำหนด (ในภาษาโปรแกรมซี) ซึ่งระบุไว้อย่างชัดเจนใน 7.18.5.2/2
Cubbi

1
+1 สำหรับการจัดหา kludge ที่ถูกต้องและใช้งานได้ บางคนมีงานทำคนอื่นมีมาตรฐาน
Mikhail

5
@ มิคาอิล: งานของคุณควรมีการเขียนโค้ดที่เป็นไปตามมาตรฐาน ฉันจะหลีกเลี่ยงการใช้สิ่งที่คุณเขียนในอนาคต
Ed S.

4

อีกวิธีหนึ่งที่เป็นไปได้ (ด้วยตนเอง) คือ

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

ฉันไม่สามารถใช้ fflush หรือ cin.flush () กับ CLion ได้ดังนั้นสิ่งนี้จึงมีประโยชน์


ลูปไม่มีที่สิ้นสุดสำหรับฉัน
StarWind0

มันใช้งานได้ก็ต่อเมื่อมีจุดสิ้นสุดของบรรทัดเท่านั้นมิฉะนั้นลูปไม่มีที่สิ้นสุด
Bobul Mentol

2

วิธีที่ง่ายที่สุด:

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

เพียงแค่วางตำแหน่งตัวชี้ cin ที่ส่วนท้ายของสตรีม stdin และ cin.clear () จะล้างแฟล็กข้อผิดพลาดทั้งหมดเช่นแฟล็ก EOF


1

สิ่งต่อไปนี้ควรใช้งานได้:

cin.flush();

ในบางระบบไม่สามารถใช้งานได้จากนั้นคุณสามารถใช้:

cin.ignore(INT_MAX);

1
เหตุใดจึงเขียนลูปด้วยตนเองเมื่อคุณสามารถบอกให้ละเว้นอักขระ INT_MAX ที่อ่านได้จนกว่าจะถึง EOF (ค่าเริ่มต้นของพารามิเตอร์ที่สอง)
Evan Teran

กันนาร์อาจจะดีกว่าถ้าแก้ไขโพสต์ของคุณเพื่อให้สอดคล้องกับสิ่งนี้ในกรณีนี้
Dana the Sane

1
เท่าที่ฉันสามารถบอกได้flushวิธีนี้ใช้สำหรับเอาต์พุตเท่านั้นและเกี่ยวข้องกับอักขระที่เขียนแล้ว
Marc van Leeuwen

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


0

cin.get() ดูเหมือนว่าจะล้างออกโดยอัตโนมัติอย่างผิดปกติพอ (อาจไม่เป็นที่ต้องการแม้ว่าจะทำให้สับสนและอาจเป็นเรื่องเจ้าอารมณ์)


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.