C++ cin.get(), cin.peek() หยุดชั่วคราว เช่นเดียวกับ stdio

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

#include <string>
#include <iostream>
#include <stdio.h>

using namespace std;

int main(){
    char c[1000];
    cin.setstate(cin.eofbit);
    cout << cin.good() << endl;
    cout << cin.eof() <<endl;
    cout << cin.get() << endl;
    cin.putback('c');
    cout << cin.get() << endl;
    cout << "Do we ever reach this?" << endl;
    while(1){
    };
    return 0;
}

ถึงอย่างไร. ปัญหาของฉันคือ cin.get(), cin.peek(), cin.ignore(), getchar() หรือฟังก์ชัน cin หรือ stdio ใดๆ ก็ตามที่คุณสามารถตั้งชื่อได้ว่าจะหยุดการทำงานของโปรแกรมของฉันชั่วคราวเมื่อสตรีมว่างเปล่า โดยไม่มีการตั้งค่า EOF บิตหรืออะไรก็ได้ สิ่งนี้ทำให้ฉันรำคาญ เนื่องจากฉันต้องการตรวจสอบว่ามีอะไรอยู่ในสตรีมหรือไม่ เพื่อที่ฉันจะได้เคลียร์มันได้ เนื่องจาก allowance() จะหยุดชั่วคราวเสมอ

วิธีเดียวที่ฉันสามารถทำงานได้คือ 'istream::readsome' ฉันโหลดสิ่งนี้ลงในอาร์เรย์ถ่านแล้วพิมพ์โดยใช้ cout มันพิมพ์สัญลักษณ์ยาวๆ ที่ฉันไม่รู้จัก (แต่ละอันเป็นสัญลักษณ์เฉพาะตัว)

http://gyazo.com/e3ee65cdad7ed5cc7b2ce2307ca58c90

โยนเป็นจำนวนเต็มออกมาเป็น -52 ซึ่งไม่เท่ากับสิ่งใดใน ASCII หรือ Unicode

ฉันกำลังรวบรวมโดยใช้ Visual C++ Express 2010

ช่วยหน่อยนะครับ ผมงงมาก ณ จุดนี้ ฉันเพียงต้องการอ่านตัวอักษร/ล้างสตรีมของฉัน โดยไม่หยุดชั่วคราวหากไม่มีสิ่งใดอยู่ ฉันใช้เวลา 3 ชั่วโมงในการพยายามแก้ไขปัญหานี้ ถอนหายใจ


person user1819357    schedule 12.11.2012    source แหล่งที่มา
comment
sync() ละทิ้งสิ่งที่เหลืออยู่ในบัฟเฟอร์ แต่ไม่รับประกันพฤติกรรมดังกล่าว   -  person chris    schedule 13.11.2012
comment
ขอบคุณ ฉันจะดูมัน แต่มีวิธีที่รับประกันได้หรือวิธีป้องกันการหยุดชั่วคราวหากฉันทำ cin.ignore หรือ cin.peek?   -  person user1819357    schedule 13.11.2012
comment
OTOH ด้วยการตรวจสอบผลลัพธ์ของการดำเนินการ I/O ของคุณอย่างถูกต้อง คุณไม่ควรมาถึงจุดที่คุณไม่รู้ว่าสตรีมว่างเปล่าหรือไม่   -  person jrok    schedule 13.11.2012
comment
แต่ฉันไม่แน่ใจว่าจะตรวจสอบได้อย่างถูกต้องได้อย่างไรว่าฉันไม่สามารถตรวจสอบสิ่งที่เหลืออยู่ในสตรีมโดยไม่ได้หยุดโปรแกรมชั่วคราวโดยไม่ตั้งใจ แถมยังควรตั้งค่าบิต EOF ไว้ด้วยใช่หรือไม่? นั่นเป็นเพียงไม่ได้ถูกตั้งค่า   -  person user1819357    schedule 13.11.2012
comment
หากต้องการตั้งค่าบิต EOF จากคอนโซล ให้พิมพ์ Ctrl + Z   -  person Jesse Good    schedule 13.11.2012
comment
นั่นไม่ใช่สิ่งที่ฉันหมายถึงแม้ว่าเจสซี่ เมื่อฉันพยายามแยกอักขระออกจากสตรีมว่าง แทนที่จะตั้งค่าบิต EOF (ดังที่กล่าวไว้ใน cplusplus.com) บิตนั้นจะรออินพุต แม้ว่าฉันจะมองแค่ตัวละครตัวต่อไปก็ตาม   -  person user1819357    schedule 13.11.2012
comment
@ user1819357: ใช่นั่นคือสิ่งที่ควรทำ (ฉันไม่รู้ว่า cplusplus.com พูดอะไร) ฉันไม่เข้าใจว่าเหตุใด std::getline และ std::string จึงไม่เพียงพอ   -  person Jesse Good    schedule 13.11.2012
comment
ดูเหมือนว่าจะต้องเป็นเช่นนั้น ฉันแค่ต้องการความยืดหยุ่นเพิ่มเติมจากการพยายามอ่านสตรีมโดยไม่ต้องดึงโปรแกรมทั้งหมด Imalso แค่พยายามทำความเข้าใจว่าทำไมมันถึงดูเหมือนมีพฤติกรรมไม่ดี อาจเป็นปัญหาของคอมไพเลอร์หรือไม่?   -  person user1819357    schedule 13.11.2012


คำตอบ (1)


หากต้องการกำจัดอักขระทั้งหมดที่ทราบว่ามีอยู่ คุณสามารถใช้ std::istream::ignore() ร่วมกับ std::streambuf::in_avail():

std::cin.ignore(std::cin.rdbuf()->in_avail());

อย่างไรก็ตาม ฉันเดาว่านี่ไม่ได้ทำสิ่งที่คุณต้องการจริงๆ: ออบเจ็กต์สตรีมมาตรฐานจะอ่านอะไรก็ตามที่ระบบปฏิบัติการมอบให้ โดยทั่วไป โหมดเริ่มต้นสำหรับอินพุตที่เชื่อมต่อกับหน้าต่างคอนโซลบางประเภทคือการบัฟเฟอร์บรรทัดอินพุต จำนวนอักขระที่ส่งให้กับสตรีมจริงๆ นั้นค่อนข้างไม่ได้กำหนดไว้

หากต้องการตรวจสอบว่ามีอินพุตอยู่ในสตรีมอินพุตหรือไม่ คุณต้องใช้วิธีการเฉพาะแพลตฟอร์ม ไลบรารี C++ มาตรฐานไม่มีการตรวจสอบแบบไม่บล็อกเพื่อดูว่าข้อมูลใหม่มาถึงใน std::cin หรือไม่ บนระบบ POSIX คุณสามารถใช้ poll() กับ file descriptor 0 เพื่อดูว่า std::cin มีข้อมูลใดๆ หรือไม่ ฉันไม่รู้สิ่งที่จำเป็นสำหรับระบบที่ไม่ใช่ POSIX

person Dietmar Kühl    schedule 12.11.2012
comment
ฉันมีซอเกี่ยวกับเรื่องนี้ IN_avail ส่งคืน 1 เสมอ ไม่ว่าฉันจะใส่อักขระกลับเข้าไปใน cin กี่ตัวก็ตาม . วิธีเดียวที่จะล้างข้อมูลได้ก็คือการซิงค์ () แถมเพิกเฉยตัดสินใจหยุดเรื่องต่างๆ ไว้ชั่วคราว ถอนหายใจ ขอบคุณสำหรับการตอบกลับ ฉันจะค้นหาสิ่งที่สามารถตรวจสอบได้ใน windows ต่อไป - person user1819357; 13.11.2012
comment
@ user1819357 คุณพบวิธีตรวจสอบบน Windows หรือไม่? - person Thomas Ibbotson; 05.08.2019