đặt lại một chuỗi chuỗi


86

Làm cách nào để "đặt lại" trạng thái của một dòng chuỗi về trạng thái khi tôi tạo nó?

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

Câu trả lời:


134

Đây là cách tôi thường làm:

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

Cảm ơn; gỡ lỗi C ++ của người khác và cần điều này để loại bỏ lỗi vi phạm quyền truy cập mà họ gặp phải do không thực hiện phương thức .clear (). Hoạt động tốt trên hộp intel nhưng mỗi lần xuất hiện trên máy AMD.
Chris Townsend

3
Thật không may là clearkhông thiết lập lại trình thao tác io. Ví dụ không đạt kiểm tra: std :: stringstream ss; ss << "Hello" << std :: setw (15) << "World" << std :: setw (15); đặt lại (ss); ss << "Xin chào Thế giới"; khẳng định ("Xin chào Thế giới" == buf.str ()); // không thành công, chọn std cuối cùng :: setw
GameSalutes

9

tôi sẽ làm

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

Chỉnh sửa: đã sửa lỗi do christianparpart và Nemo báo cáo. Cảm ơn.

Tái bút: Đoạn mã trên tạo một đối tượng dòng chuỗi mới trên ngăn xếp và hoán đổi mọi thứ ssvới những đối tượng trong đối tượng mới.

Ưu điểm:

  1. Nó đảm bảo ssbây giờ sẽ ở trạng thái mới.
  2. Đối tượng mới được tạo nội tuyến và trên ngăn xếp, để trình biên dịch có thể dễ dàng tối ưu hóa mã. Cuối cùng, nó sẽ giống như đặt lại tất cả ssdữ liệu bên trong về trạng thái ban đầu.

Hơn:

  1. So với toán tử gán: Phương thức hoán đổi STL có thể nhanh hơn toán tử gán trong trường hợp đối tượng mới có bộ đệm được cấp phát trong heap. Trong trường hợp như vậy, toán tử gán phải cấp phát bộ đệm cho đối tượng mới, sau đó CÓ THỂ cần cấp phát bộ đệm khác cho đối tượng cũ, rồi sao chép dữ liệu từ bộ đệm của đối tượng mới sang bộ đệm mới của đối tượng cũ. Rất dễ dàng để thực hiện một hoán đổi nhanh, chẳng hạn như hoán đổi các con trỏ của bộ đệm.

  2. C ++ 11. Tôi đã thấy một số triển khai của toán tử chuyển nhượng di chuyển chậm hơn so với hoán đổi, mặc dù điều đó có thể được khắc phục, nhưng có lẽ nhà phát triển STL sẽ không muốn để lại một đối tượng đã di chuyển với nhiều dữ liệu

  3. std::move()không đảm bảo đối tượng đã di chuyển được làm trống. return std::move(m_container);không xóa m_container. Vì vậy, bạn sẽ phải làm

    auto to_return (std :: move (m_container)); m_container.clear (); quay lại_trở_lại;

Không thể tốt hơn

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

bởi vì cái sau đảm bảo nó sẽ không sao chép bộ đệm.

Vì vậy, tôi luôn thích swap()miễn là nó phù hợp.


2
Bạn nên giải thích tại sao bạn sẽ làm điều này. Bản thân mã này không quá hữu ích.
Machavity

1
Mặc dù câu trả lời này có thể đúng, vui lòng thêm một số giải thích. Truyền đạt logic cơ bản quan trọng hơn là chỉ đưa ra mã, vì nó giúp OP và các trình đọc khác tự khắc phục vấn đề này và các vấn đề tương tự.
CodeMouse92

Tôi thích giải pháp. Nó rất ngắn, và cùng một mẫu hoạt động trên thực tế cho tất cả các kiểu dữ liệu std.
martinus

1
Câu trả lời này không hoàn toàn đúng vì bạn có thể không liên kết với một biến tạm thời, tức là bạn tạo một biến tạm thời để hoán đổi luồng chuỗi rỗng mới được tạo (tạm thời) với luồng "ss" hiện có. Không cho phép.
christianparpart

Điều này không phải chịu tất cả chi phí xây dựng một ngôn ngữ, điều mà việc đặt lại chuỗi chuỗi được cho là phải tránh?
hạn

2

Dựa trên câu trả lời ở trên, chúng tôi cũng cần đặt lại bất kỳ định dạng nào. Trong tất cả, chúng tôi đang đặt lại nội dung bộ đệm, cờ trạng thái luồng và mọi định dạng về mặc định của chúng khi một cá thể std :: stringstream mới được tạo.

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

    stream.str(std::string());
    stream.clear();
    stream.copyfmt(initial);
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.