การรีเซ็ตสตรีมสตริง


86

ฉันจะ "รีเซ็ต" สถานะของสตรีมสตริงให้เป็นแบบเดิมเมื่อสร้างได้อย่างไร

int firstValue = 1;
int secondValue = 2;

std::wstringstream ss;

ss << "Hello: " << firstValue;

std::wstring firstText(ss.str());

//print the value of firstText here


//How do I "reset" the stringstream here?
//I would like it behave as if I had created
// stringstream ss2 and used it below.


ss << "Bye: " << secondValue;

std::wstring secondText(ss.str());

//print the value of secondText here

คำตอบ:


135

นี่คือวิธีที่ฉันมักจะทำ:

ss.str("");
ss.clear(); // Clear state flags.

ขอบคุณ; การดีบัก C ++ ของคนอื่นและต้องการสิ่งนี้เพื่อแยกแยะข้อผิดพลาดการละเมิดการเข้าถึงที่ได้รับเนื่องจากไม่ได้ทำเมธอด. clear () ทำงานได้ดีบนกล่อง intel แต่ puked ทุกครั้งบนเครื่อง AMD
Chris Townsend

3
น่าเสียดายที่clearไม่ได้รีเซ็ตตัวปรับแต่ง io ตัวอย่างการทดสอบความล้มเหลว: std :: stringstream ss; ss << "สวัสดี" << std :: setw (15) << "World" << std :: setw (15); รีเซ็ต (ss); ss << "สวัสดีชาวโลก"; ยืนยัน ("สวัสดีชาวโลก" == buf.str ()); // ล้มเหลวหยิบ std สุดท้าย :: setw
GameSalutes

9

ฉันจะทำ

std::wstringstream temp;
ss.swap(temp);

แก้ไข: แก้ไขข้อผิดพลาดที่รายงานโดย christianparpart และ Nemo ขอบคุณ.

PS: โค้ดด้านบนสร้างออบเจ็กต์สตริงสตรีมใหม่บนสแต็กและสลับทุกอย่างssกับสิ่งที่อยู่ในอ็อบเจ็กต์ใหม่

ข้อดี:

  1. ssตอนนี้การรับประกันจะอยู่ในสถานะใหม่
  2. อ็อบเจ็กต์ใหม่ถูกสร้างขึ้นแบบอินไลน์และบนสแต็กเพื่อให้คอมไพเลอร์สามารถปรับโค้ดให้เหมาะสมได้อย่างง่ายดาย ในตอนท้ายจะเหมือนกับการรีเซ็ตssข้อมูลภายในทั้งหมดให้เป็นสถานะเริ่มต้น

มากกว่า:

  1. เมื่อเทียบกับตัวดำเนินการกำหนดวิธีการแลกเปลี่ยน STL อาจเร็วกว่าตัวดำเนินการกำหนดในกรณีที่อ็อบเจ็กต์ใหม่มีบัฟเฟอร์ที่จัดสรรในฮีป ในกรณีเช่นนี้ตัวดำเนินการกำหนดจะต้องจัดสรรบัฟเฟอร์สำหรับออบเจ็กต์ใหม่จากนั้นอาจต้องจัดสรรบัฟเฟอร์อื่นสำหรับอ็อบเจ็กต์เก่าจากนั้นคัดลอกข้อมูลจากบัฟเฟอร์ของอ็อบเจ็กต์ใหม่ไปยังบัฟเฟอร์ใหม่ของอ็อบเจ็กต์เก่า มันง่ายมากที่จะใช้การแลกเปลี่ยนที่รวดเร็วซึ่งเพียงแค่เปลี่ยนพอยน์เตอร์ของบัฟเฟอร์

  2. C ++ 11. ฉันเคยเห็นการใช้งานตัวดำเนินการกำหนดการย้ายที่ช้ากว่าการแลกเปลี่ยนแม้ว่าจะสามารถแก้ไขได้ แต่ผู้พัฒนา STL อาจไม่ต้องการทิ้งวัตถุที่ย้ายพร้อมข้อมูลจำนวนมาก

  3. std::move()ไม่รับประกันว่าวัตถุที่ย้ายจะว่างเปล่า return std::move(m_container);ไม่ล้าง m_container ดังนั้นคุณจะต้องทำ

    to_return อัตโนมัติ (std :: move (m_container)); m_container.clear (); กลับ to_return;

ซึ่งไม่สามารถดีไปกว่า

auto to_return;
m_container.swap(to_return);
return to_return;

เพราะอย่างหลังรับประกันว่าจะไม่คัดลอกบัฟเฟอร์

ดังนั้นฉันมักจะชอบswap()ตราบเท่าที่มันพอดี


2
คุณควรอธิบายว่าทำไมคุณถึงทำเช่นนี้ รหัสนี้ไม่ได้มีประโยชน์มากนัก
Machavity

1
แม้ว่าคำตอบนี้อาจถูกต้องโปรดเพิ่มคำอธิบาย การให้ตรรกะพื้นฐานมีความสำคัญมากกว่าแค่การให้รหัสเพราะจะช่วยให้ OP และผู้อ่านรายอื่นแก้ไขปัญหานี้และปัญหาที่คล้ายกันได้ด้วยตนเอง
CodeMouse92

ฉันชอบวิธีแก้ปัญหา มันสั้นมากและเทมเพลตเดียวกันก็ใช้ได้กับประเภทข้อมูล std แทบทั้งหมด
martinus

1
คำตอบนี้ไม่ถูกต้องนักเนื่องจากคุณไม่สามารถเชื่อมโยงกับชั่วคราวได้นั่นคือคุณสร้างตัวแปรชั่วคราวเพื่อสลับสตรีมสตริงว่างที่สร้างขึ้นใหม่ (ชั่วคราว) กับ "ss" ที่มีอยู่ ไม่ได้รับอนุญาต.
christianparpart

สิ่งนี้ไม่ก่อให้เกิดค่าใช้จ่ายทั้งหมดในการสร้างโลแคลซึ่งการรีเซ็ตสตรีมสตริงควรหลีกเลี่ยงหรือไม่
แคป

2

จากคำตอบข้างต้นเราจำเป็นต้องรีเซ็ตการจัดรูปแบบใด ๆ เรากำลังรีเซ็ตเนื้อหาบัฟเฟอร์แฟล็กสถานะสตรีมและการจัดรูปแบบใด ๆ เป็นค่าเริ่มต้นเมื่อสร้างอินสแตนซ์ std :: stringstream ใหม่

void reset(std::strinstream& stream)
{
    const static std::stringstream initial;

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