ฉันต้องการล้างข้อมูลและนำ ostringstream กลับมาใช้ใหม่ (และบัฟเฟอร์พื้นฐาน) เพื่อที่แอปของฉันจะได้ไม่ต้องทำการจัดสรรให้มากนัก ฉันจะรีเซ็ตวัตถุเป็นสถานะเริ่มต้นได้อย่างไร
ฉันต้องการล้างข้อมูลและนำ ostringstream กลับมาใช้ใหม่ (และบัฟเฟอร์พื้นฐาน) เพื่อที่แอปของฉันจะได้ไม่ต้องทำการจัดสรรให้มากนัก ฉันจะรีเซ็ตวัตถุเป็นสถานะเริ่มต้นได้อย่างไร
คำตอบ:
ฉันเคยใช้ลำดับความชัดเจนและความแข็งแกร่งในอดีต:
// clear, because eof or other bits may be still set.
s.clear();
s.str("");
ซึ่งได้ทำสิ่งนี้สำหรับสตริงสตรีมทั้งอินพุตและเอาต์พุต หรือคุณสามารถล้างด้วยตนเองจากนั้นค้นหาลำดับที่เหมาะสมเพื่อเริ่มต้น:
s.clear();
s.seekp(0); // for outputs: seek put ptr to start
s.seekg(0); // for inputs: seek get ptr to start
ซึ่งจะป้องกันไม่ให้มีการจัดสรรstr
ซ้ำโดยการเขียนทับสิ่งที่อยู่ในบัฟเฟอร์เอาต์พุตในปัจจุบันแทน ผลลัพธ์เป็นดังนี้:
std::ostringstream s;
s << "hello";
s.seekp(0);
s << "b";
assert(s.str() == "bello");
หากคุณต้องการใช้สตริงสำหรับฟังก์ชัน c คุณสามารถใช้ได้โดยstd::ends
ใส่ค่าว่างในการยกเลิกดังนี้:
std::ostringstream s;
s << "hello";
s.seekp(0);
s << "b" << std::ends;
assert(s.str().size() == 5 && std::strlen(s.str().data()) == 1);
std::ends
เป็นความสัมพันธ์ของการเลิกใช้งานstd::strstream
ซึ่งสามารถเขียนโดยตรงไปยังอาร์เรย์ถ่านที่คุณจัดสรรไว้บนสแต็ก คุณต้องแทรกโมฆะการยุติด้วยตนเอง อย่างไรก็ตามstd::ends
ไม่ได้เลิกใช้งานฉันคิดว่าเพราะมันยังมีประโยชน์เหมือนในกรณีข้างต้น
s.str("");
แทน auto str = s.str(); auto cstr = str.c_str(); file << cstr; s.clear(); s.seekp(0); s << ends;
boost::any a = 1; std::ostringstream buffer; buffer << a << std::ends; EXPECT_EQ( buffer.str(), "any<(int)1>" );
TestUtilsTest.cpp:27: Failure Expected: buffer.str() Which is: "any<(int)1>\0" To be equal to: "any<(int)1>"
และถ้าฉันใช้ซ้ำกับสตริงที่มีความยาวต่างกันฉันจะเหลือบิต
s.seekp(0); s << std::ends; s.seekp(0);
ดูเหมือนว่าการostr.str("")
โทรจะหลอกลวง
หากคุณกำลังจะล้างบัฟเฟอร์ด้วยวิธีที่จะทำให้ถูกล้างก่อนที่จะใช้งานครั้งแรกคุณจะต้องเพิ่มบางอย่างลงในบัฟเฟอร์ก่อนด้วย MSVC
struct Foo {
std::ostringstream d_str;
Foo() {
d_str << std::ends; // Add this
}
void StrFunc(const char *);
template<class T>
inline void StrIt(const T &value) {
d_str.clear();
d_str.seekp(0); // Or else you'll get an error with this seek
d_str << value << std::ends;
StrFunc(d_str.str().c_str()); // And your string will be empty
}
};
clear
จะทำให้เกิดfailbit
จะเป็นชุดถ้ากระแสที่ยังว่างอยู่ ในขณะที่โทรเพียงแค่seekp
ควรกลับมาหากไม่มีสตรีม
คุณไม่ทำ ใช้สตรีมที่มีชื่อต่างกันสองสตรีมเพื่อความชัดเจนและปล่อยให้คอมไพเลอร์การปรับให้เหมาะสมคิดออกว่าสามารถนำสตรีมเก่ามาใช้ซ้ำได้
ostringstream
(ตามข้อมูลที่อ่าน) จากนั้นต้องเขียนสตริงที่สร้างขึ้นในที่ostringstream
ใดที่หนึ่งเป็นครั้งคราว (เช่นหลังจากอ่านลำดับอักขระบางตัวแล้ว) และเริ่มต้น สร้างสตริงใหม่