Bir ostringstream nasıl yeniden kullanılır?


117

Bir ostringstream'i (ve temeldeki tamponu) temizleyip yeniden kullanmak istiyorum, böylece uygulamamın çok sayıda ayırma yapması gerekmez. Nesneyi başlangıç ​​durumuna nasıl sıfırlarım?


Yanıtlar:


156

Geçmişte bir dizi clear ve str kullandım:

// clear, because eof or other bits may be still set. 
s.clear();
s.str("");

Hem girdi hem de çıktı dizesi akışları için bir şey yaptı. Alternatif olarak, manuel olarak temizleyebilir ve ardından başlamak için uygun sırayı arayabilirsiniz:

s.clear();
s.seekp(0); // for outputs: seek put ptr to start
s.seekg(0); // for inputs: seek get ptr to start

Bu, strhalihazırda çıktı tamponunda bulunanların üzerine yazarak yapılan bazı yeniden tahsisleri önleyecektir . Sonuçlar şuna benzer:

std::ostringstream s;
s << "hello";
s.seekp(0);
s << "b";
assert(s.str() == "bello");

Dizeyi c işlevleri için kullanmak istiyorsanız, aşağıdaki std::endsgibi sonlandırıcı bir boş koyarak kullanabilirsiniz :

std::ostringstream s;
s << "hello";
s.seekp(0);
s << "b" << std::ends;
assert(s.str().size() == 5 && std::strlen(s.str().data()) == 1);

std::endsstd::strstreamyığıt üzerinde ayırdığınız bir char dizisine doğrudan yazabilen , kullanımdan kaldırılmış bir kalıntıdır . Manuel olarak bir sonlandırma boşluğu eklemeniz gerekiyordu. Ancak, std::endskullanımdan kaldırılmadı, çünkü yukarıdaki durumlarda olduğu gibi hala yararlı olduğunu düşünüyorum.


Bir ostream ile s.str () kullanmaya çalışıyorum. Boyut karıştırıyor (ilk karakterin boş olduğunu görebiliyorum ama çok daha fazlasını yazdırıyor). Str uzunluğunu düzeltmenin iyi bir yolu var mı? s.str (). c_str () kullanıyorum; ATM ve güzel çalışıyor

Aslında bu bile doğru değil. Onun s.str("");yerine ben yaptım . auto str = s.str(); auto cstr = str.c_str(); file << cstr; s.clear(); s.seekp(0); s << ends;

std :: uçları google testinde benim için çalışmıyor 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>" ve farklı uzunluktaki dizelerle yeniden kullanırsam bitlerin üzerinde
kalıyorum

Yeniden tahsisi önlemek istiyorsanız, Alternatif doğru cevaptır. Ve eğer yeniden tahsis etmeden gerçekten "yeni başlamak" istiyorsanız, std :: end gönderdikten sonra seekp (0) 'ı tekrar çağırın. s.seekp(0); s << std::ends; s.seekp(0);
Chip Grandits

5

Görünüşe göre ostr.str("")arama hile yapıyor.


9
Bunun ostringstream'deki temel tamponu yeniden kullanmayacağına dikkat çekmek gerekir - sadece yeni bir tampon atar. Dolayısıyla, ostringstream nesnesini yeniden kullanırken, hala iki tampon ayırıyorsunuz. Ostringstream'in sizin istediğiniz şekilde yeniden kullanılmak üzere tasarlandığını sanmıyorum.
razlebe

2
Ayrıca, .clear () işlevinin yaptığı durumu da temizlemez. Katılıyorum, gerçekten böyle kullanılması amaçlanmadı. Emin olmak için yeni bir tane oluşturun. Sadece profil çıkarırsan bunun bir fark yaratıp yaratmadığını öğrenebilirsin.
Brian Neal

1
Sgreeve Brian, bu doğru. Bununla birlikte, yukarıdaki litb yönteminin std :: uçlarının kullanımını nasıl gerektirdiğine dikkat edin. Arabelleği yeniden kullanır, ancak dizge akışları ile her zamanki gibi farklı kodlamanızı sağlar (normalde std :: uçları kullanmazsınız).
Diego Sevilla

2

Arabelleği, ilk kullanımdan önce temizlenmesine neden olacak şekilde temizleyecekseniz, önce tampona w / MSVC ile bir şey eklemeniz gerekir.

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
    }
};

VS2012'de başarısız davranışı görmüyorum. Ayrıca, arama clearolacaktır nedenfailbit Akış boş olup olmadığını tespit eder. Sadece arama yapılırken, seekpakış yoksa geri dönmelidir.
Jonathan Mee

0

Yapmıyorsun. Netlik için iki farklı adlandırılmış akış kullanın ve optimize eden derleyicinin eskisini yeniden kullanabileceğini anlamasına izin verin.


4
Kodun giriş verileri üzerinde döngü yaptığı, bir'e yazdığı ostringstream(okunan verilere göre) ve daha sonra ostringstreamzaman zaman bir yere yerleşik dizgiyi yazması gerektiği (örneğin, belirli bir karakter dizisi okunduktan sonra) kullanım durumunu düşünün ve başlayın yeni bir ip oluşturmak.
Andre Holzner
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.