ความแตกต่างระหว่าง istringstream, ostringstream และ stringstream คืออะไร / ทำไมไม่ใช้ stringstream ในทุกกรณี?


163

เมื่อผมจะใช้std::istringstream, std::ostringstreamและstd::stringstreamและทำไมฉันจึงไม่ควรใช้std::stringstreamในทุกสถานการณ์ (จะมีผู้ใดปัญหาประสิทธิภาพการทำงานรันไทม์?)

สุดท้ายมีอะไรที่ไม่ดีเกี่ยวกับเรื่องนี้ (แทนที่จะใช้สตรีมเลย):

std::string stHehe("Hello ");

stHehe += "stackoverflow.com";
stHehe += "!";

คำตอบ:


119

โดยส่วนตัวฉันพบว่าหายากมากที่ฉันต้องการทำการสตรีมเข้าและออกจากสตรีมสตริงเดียวกัน

ฉันมักจะต้องการเริ่มต้นกระแสจากสตริงแล้วแยกมัน; หรือสตรีมสิ่งต่าง ๆ ไปยังสตรีมสตริงแล้วแยกผลลัพธ์และเก็บไว้

หากคุณสตรีมมิ่งไปและกลับจากสตรีมเดียวกันคุณจะต้องระมัดระวังอย่างมากเกี่ยวกับสถานะสตรีมและสถานะสตรีม

ใช้ 'เพียง' istringstreamหรือostringstreamดีกว่าเป็นการแสดงออกถึงเจตนาของคุณและช่วยให้คุณตรวจสอบความผิดพลาดบางอย่างกับโง่เช่นการใช้อุบัติเหตุของVS<<>>

มีอาจจะเป็นบางส่วนปรับปรุงประสิทธิภาพการทำงาน แต่ฉันจะไม่ได้รับการมองหาที่แรกที่

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

std::string stHehe( "Hello stackoverflow.com!" );

22

A stringstreamค่อนข้างใหญ่กว่าและอาจมีประสิทธิภาพลดลงเล็กน้อย - การสืบทอดหลายอย่างสามารถต้องการการปรับเปลี่ยนไปยังตัวชี้ vtable ความแตกต่างที่สำคัญคือ (อย่างน้อยในทางทฤษฎี) แสดงความตั้งใจของคุณได้ดีขึ้นและป้องกันคุณจากการใช้โดยไม่ตั้งใจ>>ที่คุณตั้งใจ<<(หรือในทางกลับกัน) OTOH stringstreamความแตกต่างที่มีขนาดเล็กพอที่โดยเฉพาะอย่างยิ่งสำหรับบิตอย่างรวดเร็วของรหัสการสาธิตและเช่นผมใช้ขี้เกียจและเพียงแค่ ฉันไม่สามารถค่อนข้างจำครั้งสุดท้ายที่ฉันตั้งใจใช้<<เมื่อฉันตั้งใจ>>เพื่อที่จะให้ฉันบิตของความปลอดภัยที่ดูเหมือนว่าส่วนใหญ่ทางทฤษฎี (โดยเฉพาะอย่างยิ่งเพราะถ้าคุณทำทำให้ผิดพลาดดังกล่าวก็มักจะจะจริงๆที่เห็นได้ชัดเกือบจะในทันที)

ไม่มีอะไรผิดปกติเพียงแค่ใช้สตริงตราบใดที่มันบรรลุสิ่งที่คุณต้องการ หากคุณเพียงแค่ใส่สายเข้าด้วยกันมันง่ายและทำงานได้ดี หากคุณต้องการจัดรูปแบบข้อมูลประเภทอื่น ๆstringstreamจะสนับสนุนนั้นและสตริงส่วนใหญ่จะไม่


17

ในกรณีส่วนใหญ่คุณจะไม่พบว่าตัวเองต้องการทั้งอินพุทและเอาท์พุทบนสายน้ำเดียวกันดังนั้นการใช้std::ostringstreamและstd::istringstreamทำให้ความตั้งใจของคุณชัดเจน นอกจากนี้ยังป้องกันไม่ให้คุณพิมพ์โอเปอเรเตอร์ที่ผิดพลาด ( <<vs >>) โดยไม่ตั้งใจ

เมื่อคุณต้องการดำเนินการทั้งสองอย่างในสตรีมเดียวกันคุณจะต้องใช้เวอร์ชันวัตถุประสงค์ทั่วไปอย่างชัดเจน

ปัญหาด้านประสิทธิภาพจะเป็นสิ่งที่คุณกังวลน้อยที่สุดความชัดเจนเป็นข้อได้เปรียบหลัก

ในที่สุดก็ไม่มีอะไรผิดปกติกับการใช้สตริงผนวกตามที่คุณต้องสร้างสตริงบริสุทธิ์ คุณไม่สามารถใช้เพื่อรวมตัวเลขอย่างที่คุณสามารถทำได้ในภาษาเช่น perl


8

istringstream สำหรับอินพุต, ostringstream สำหรับเอาต์พุต stringstream เป็นอินพุตและเอาต์พุต คุณสามารถใช้สตริงสตรีมได้ทุกที่ อย่างไรก็ตามถ้าคุณให้วัตถุของคุณแก่ผู้ใช้คนอื่นและมันใช้โอเปอเรเตอร์ >> ในขณะที่คุณกำลังรอวัตถุที่เขียนอย่างเดียวคุณจะไม่พอใจ ;-)

PS: ไม่มีอะไรเลวร้ายเกี่ยวกับมันเพียงแค่ปัญหาด้านประสิทธิภาพ


2

ในการตอบคำถามที่สามของคุณ: ไม่นั่นสมเหตุสมผลอย่างยิ่ง ข้อดีของการใช้สตรีมคือคุณสามารถป้อนค่าใด ๆ ที่ได้operator<<กำหนดไว้ในขณะที่คุณสามารถเพิ่มสตริง (C ++ หรือ C) ลงใน a std::stringเท่านั้น


1

สันนิษฐานได้ว่าเมื่อมีการแทรกหรือการแยกเท่านั้นที่เหมาะสมสำหรับการดำเนินการของคุณคุณสามารถใช้หนึ่งในรุ่นนำหน้า 'i' หรือ 'o' เพื่อแยกการดำเนินการที่ไม่ต้องการ

หากไม่สำคัญคุณสามารถใช้รุ่น i / o

การต่อสตริงที่คุณแสดงนั้นถูกต้องสมบูรณ์ แม้ว่าการต่อข้อมูลโดยใช้ stringstream นั้นเป็นไปได้ที่ไม่ใช่คุณสมบัติที่มีประโยชน์ที่สุดของ stringstreams ซึ่งสามารถแทรกและแยก POD และชนิดข้อมูลนามธรรมได้


1

std :: ostringstream :: str () สร้างสำเนาของเนื้อหาของสตรีมซึ่งเพิ่มการใช้หน่วยความจำเป็นสองเท่าในบางสถานการณ์ คุณสามารถใช้ std :: stringstream และฟังก์ชัน rdbuf () แทนเพื่อหลีกเลี่ยงปัญหานี้

รายละเอียดเพิ่มเติมที่นี่: วิธีการเขียน ostringstream โดยตรงไปยังศาล


0

เหตุใดจึงเปิดไฟล์สำหรับการเข้าถึงแบบอ่าน / เขียนหากคุณต้องการอ่านจากไฟล์เท่านั้น?

ถ้าหลายกระบวนการจำเป็นต้องอ่านจากไฟล์เดียวกัน

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