การล้างบัฟเฟอร์หมายถึงอะไร?


100

ฉันกำลังเรียนรู้ C ++ และพบบางสิ่งที่ฉันไม่เข้าใจ:

บัฟเฟอร์เอาต์พุตสามารถล้างออกได้อย่างชัดเจนเพื่อบังคับให้เขียนบัฟเฟอร์ โดยค่าเริ่มต้นการอ่านcinวูบวาบcout; coutจะถูกล้างเมื่อโปรแกรมสิ้นสุดตามปกติ

ดังนั้นการล้างบัฟเฟอร์ (ตัวอย่างเช่นบัฟเฟอร์เอาต์พุต): การดำเนินการนี้จะล้างบัฟเฟอร์โดยการลบทุกอย่างในนั้นหรือล้างบัฟเฟอร์โดยการส่งออกทุกอย่างในนั้น? หรือการล้างบัฟเฟอร์หมายถึงสิ่งที่แตกต่างอย่างสิ้นเชิง?

คำตอบ:


128

ลองเขียนลงไฟล์ นี่เป็นการดำเนินการที่มีราคาแพง หากในโค้ดของคุณคุณเขียนทีละไบต์การเขียนแต่ละไบต์จะมีค่าใช้จ่ายสูงมาก ดังนั้นวิธีทั่วไปในการปรับปรุงประสิทธิภาพคือการจัดเก็บข้อมูลที่คุณเขียนไว้ในบัฟเฟอร์ชั่วคราว เฉพาะเมื่อมีข้อมูลจำนวนมากเท่านั้นที่บัฟเฟอร์จะถูกเขียนลงในไฟล์ ด้วยการเลื่อนการเขียนและการเขียนบล็อกขนาดใหญ่ในครั้งเดียวประสิทธิภาพจะดีขึ้น

ด้วยเหตุนี้การล้างบัฟเฟอร์จึงเป็นการถ่ายโอนข้อมูลจากบัฟเฟอร์ไปยังไฟล์

สิ่งนี้ล้างบัฟเฟอร์โดยการลบทุกอย่างในนั้นหรือล้างบัฟเฟอร์โดยการส่งออกทุกอย่างในนั้นหรือไม่?

หลัง.


1
ขอบคุณ. อีกหนึ่งสิ่ง. การอ่าน cin flushes cout คำว่า "reading cin" หมายความว่าเมื่อผู้ใช้ป้อนข้อมูลบางอย่างหรือเมื่อผู้ใช้ได้รับแจ้งให้ป้อนข้อมูลหรือไม่
Mohamed Ahmed Nabil

4
การอ่าน cin เกิดขึ้นเมื่อคุณใช้ตัวดำเนินการสตรีมเพื่ออ่านจาก cin โดยทั่วไปคุณต้องการล้าง cout เมื่อคุณอ่านเพราะมิฉะนั้นอินพุตอาจปรากฏขึ้นก่อนพร้อมต์
David Heffernan

1
@DavidHeffernan เท่าที่ฉันรู้คุณไม่จำเป็นต้องล้าง cout ก่อน cin เพราะ cin และ cout ถูกผูกไว้ (Stroustrup, The C ++ Programming Language, [io.tie])
แข็งแกร่งขึ้น

24

คุณได้อ้างคำตอบ:

บัฟเฟอร์เอาต์พุตสามารถล้างออกได้อย่างชัดเจนเพื่อบังคับให้เขียนบัฟเฟอร์

นั่นคือคุณอาจต้อง "ล้าง" เอาต์พุตเพื่อทำให้ถูกเขียนไปยังสตรีมที่อยู่เบื้องหลัง (ซึ่งอาจเป็นไฟล์หรือในตัวอย่างที่ระบุไว้คือเทอร์มินัล)

โดยทั่วไป stdout / cout เป็นแบบ line-buffered: เอาต์พุตจะไม่ถูกส่งไปยัง OS จนกว่าคุณจะเขียนขึ้นบรรทัดใหม่หรือล้างบัฟเฟอร์อย่างชัดเจน ข้อดีคือสิ่งที่ต้องการstd::cout << "Mouse moved (" << p.x << ", " << p.y << ")" << endlทำให้เกิดการเขียนเพียงครั้งเดียวใน "ไฟล์" ที่อยู่ภายใต้แทนที่จะเป็นหกซึ่งดีกว่ามากสำหรับประสิทธิภาพ ข้อเสียคือรหัสเช่น:

for (int i = 0; i < 5; i++) {
    std::cout << ".";
    sleep(1); // or something similar
}

std::cout << "\n";

จะแสดงผล.....พร้อมกัน (สำหรับsleepการใช้งานที่แน่นอนโปรดดูคำถามนี้ ) ในกรณีเช่นนี้คุณจะต้องเพิ่ม<< std::flushเพื่อให้แน่ใจว่าเอาต์พุตจะแสดงขึ้น

การอ่านจะกระcinพริบcoutดังนั้นคุณไม่จำเป็นต้องล้างข้อมูลอย่างชัดเจนเพื่อทำสิ่งนี้:

std::string colour;
std::cout << "Enter your favourite colour: ";
std::cin >> colour;

ทำสิ่งนี้สำหรับ (int i = 0; i <5; i ++) {std :: cout << "."; นอนหลับ (1); } std :: cout << std :: endl; ไม่พิมพ์ ..... ในครั้งเดียว. มันพิมพ์ออกมาโดยใช้เวลาระหว่าง 1 มิลลิวินาที คุณจะสังเกตเห็นได้มากขึ้นเมื่อคุณใช้การนอนหลับ (1,000)
Mohamed Ahmed Nabil

@MohamedAhmedNabil ดูเหมือนว่าคุณจะสับสนsleep()(POSIX) กับSleep()(Windows)
tc

1
คำตอบเก่า แต่มีเพียงความคิดเห็นน้อยเกี่ยวกับเนื้อหาและข้อมูลเพิ่มเติมเกี่ยวกับตัวอย่าง คุณมีคุณสมบัติcoutด้วยเนมสเปซ (กล่าวคือstd::cout) แต่ไม่ได้ทำเช่นนั้นendlซึ่งควรต้องมีคุณสมบัติดังกล่าวด้วย
vol7ron

1
ฉันชอบตัวอย่างของคุณ แต่ฉันคิดว่า endl ล้างบัฟเฟอร์ แต่ในตัวอย่างของคุณ \ n จะล้างบัฟเฟอร์ ฉันสับสน.
Naz

1
@Naz \ n ไม่ล้างบัฟเฟอร์ บัฟเฟอร์จะถูกล้างเมื่อสิ้นสุดโปรแกรมในตัวอย่างของเขาเท่านั้น (บัฟเฟอร์จะถูกล้างโดยอัตโนมัติเมื่อสิ้นสุดโปรแกรม C ++) \ n น่าจะใช้สำหรับการจัดรูปแบบเท่านั้น นอกจากนี้คุณคิดถูกแล้วที่ std :: endl จะล้างบัฟเฟอร์ (เช่นกัน std :: flush แต่นั่นคือการอธิบายตัวเอง)
liamnickell

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