bir dizi akışını sıfırlama


86

Bir dizgi akışının durumunu, onu oluşturduğumdaki haline nasıl "sıfırlarım"?

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

Yanıtlar:


135

Genelde böyle yapıyorum:

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

Teşekkürler; başka birinin C ++ 'sında hata ayıklama ve buna .clear () yöntemini yapmadıkları için aldıkları bir erişim ihlali hatasını çözmek için ihtiyaç duyuyordu. Bir Intel kutusunda iyi çalıştı ama bir AMD makinesinde her seferinde kustu.
Chris Townsend

3
Maalesef cleario manipülatörlerini sıfırlamaz. Başarısız test örneği: std :: stringstream ss; ss << "Merhaba" << std :: setw (15) << "Dünya" << std :: setw (15); sıfırlama (ss); ss << "Merhaba Dünya"; assert ("Merhaba Dünya" == buf.str ()); // başarısız, son std'yi alır :: setw
GameSalutes

9

yapardım

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

Düzenleme: christianparpart ve Nemo tarafından bildirilen hata düzeltildi. Teşekkürler.

Not: Yukarıdaki kod, yığın üzerinde yeni bir dizgi akışı nesnesi oluşturur ve her şeyi ssyeni nesnede bulunanlarla değiştirir.

Avantajlar:

  1. Garanti eder ss yeni bir durumda olacağını .
  2. Yeni nesne satır içi ve yığın üzerinde oluşturulur, böylece derleyici kodu kolayca optimize edebilir. Sonunda, tüm ssdahili verileri başlangıç ​​durumuna sıfırlamak gibi olacaktır .

Daha:

  1. Atama operatörü ile karşılaştırıldığında: STL takas yöntemleri, yeni nesnenin yığın içinde ayrılmış bir arabelleğe sahip olduğu durumlarda atama operatöründen daha hızlı olabilir. Böyle bir durumda, atama operatörü yeni nesne için arabelleği tahsis etmeli, sonra eski nesne için başka bir ara bellek ayırmalı ve ardından veriyi yeni nesnenin arabelleğinden eski nesnenin yeni arabelleğine kopyalamalıdır. Örneğin tamponların işaretlerini değiştiren hızlı bir takas uygulamak çok kolaydır.

  2. C ++ 11. Takas işleminden daha yavaş olan bazı taşıma atama operatörü uygulamaları gördüm, ancak bu düzeltilebilir, ancak muhtemelen STL geliştiricisi çok fazla veriyle taşınan bir nesneyi bırakmak istemeyecektir

  3. std::move()taşınan nesnenin boşaltılacağını garanti etmez. return std::move(m_container);m_container'ı temizlemez. Yani yapmak zorunda kalacaksın

    auto to_return (std :: move (m_container)); m_container.clear (); dönüşe dön;

Hangisi daha iyi olamaz

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

çünkü ikincisi, arabellekleri kopyalamayacağını garanti eder.

Bu yüzden her zaman swap()uygun olduğu sürece tercih ederim .


2
Bunu neden yaptığını açıklamalısın . Bu kod kendi başına çok da kullanışlı değil.
Machavity

1
Bu cevap doğru olsa da, lütfen biraz açıklama ekleyin. Temel mantığı uygulamak, sadece kodu vermekten daha önemlidir, çünkü OP'nin ve diğer okuyucuların bu ve benzeri sorunları kendilerinin düzeltmesine yardımcı olur.
CodeMouse92

Çözümü beğendim. Çok kısadır ve aynı şablon hemen hemen tüm standart veri türleri için çalışır.
martinus

1
Geçici bir değişkene bağlanamayacağınız için, yani yeni (geçici olarak) oluşturulmuş boş dizgi akışını mevcut "ss" ile değiştirmek için geçici bir değişken oluşturduğunuz için bu cevap tam olarak doğru değildir. İzin verilmedi.
christianparpart

Bu, dizgi akışını sıfırlamaktan kaçınması gereken bir yerel ayar oluşturmanın tüm ek yükünü gerektirmiyor mu?
kapaklar

2

Yukarıdaki cevaba dayanarak, herhangi bir biçimlendirmeyi de sıfırlamamız gerekiyor. Sonuçta, yeni bir std :: stringstream örneği oluşturulduğunda tampon içeriğini, akım durumu bayraklarını ve herhangi bir biçimlendirmeyi varsayılan değerlerine sıfırlıyoruz.

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

    stream.str(std::string());
    stream.clear();
    stream.copyfmt(initial);
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.