ऑस्ट्रिंगस्ट्रीम का पुन: उपयोग कैसे करें?


117

मैं साफ़ करना चाहूंगा और एक ऑस्ट्रिंगस्ट्रीम (और अंतर्निहित बफर) का पुन: उपयोग करना चाहता हूं ताकि मेरे ऐप को कई आवंटन के रूप में न करना पड़े। मैं ऑब्जेक्ट को उसकी प्रारंभिक स्थिति में कैसे रीसेट करूं?


जवाबों:


156

मैंने अतीत में स्पष्ट और स्पष्ट क्रम का उपयोग किया है:

// 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");

यदि आप सी-फ़ंक्शंस के लिए स्ट्रिंग का उपयोग करना चाहते हैं, तो आप 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 () का उपयोग करने की कोशिश कर रहा हूं। आकार इसे गड़बड़ कर रहा है (मैं देख सकता हूं कि पहला चरित्र अशक्त है लेकिन यह बहुत अधिक प्रिंट करता है)। क्या स्ट्रेट लेंथ को ठीक करने का कोई अच्छा तरीका है? मैं s.str ()। c_str () का उपयोग कर रहा हूं; ATM और यह अच्छी तरह से काम करता है

वास्तव में यह भी सही नहीं है। मैंने सिर्फ इसके s.str("");बजाय किया। auto str = s.str(); auto cstr = str.c_str(); file << cstr; s.clear(); s.seekp(0); s << ends;

एसटीडी :: समाप्त होता है मेरे लिए Google परीक्षण में काम नहीं करता है 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);
चिप ग्रैंडिट्स

5

ऐसा लगता है कि ostr.str("")कॉल चाल करता है।


9
इस ओर इशारा करते हुए कि यह शुतुरमुर्ग से अंतर्निहित बफर का फिर से उपयोग नहीं करेगा - यह सिर्फ एक नया बफर प्रदान करता है। इसलिए जब आप ओस्ट्रिंगस्ट्रीम ऑब्जेक्ट का पुन: उपयोग कर रहे हैं, तो आप अभी भी दो बफ़र्स आवंटित कर रहे हैं। मुझे नहीं लगता कि आप जिस तरह से इरादा करना चाहते हैं, उसमें ओस्ट्रिंगस्ट्रीम को फिर से इस्तेमाल करने के लिए डिज़ाइन किया गया है।
रज़लेबे

2
यह राज्य को भी स्पष्ट नहीं करता है, जो .clear () करता है। मैं सहमत हूँ, यह वास्तव में इस तरह इस्तेमाल करने के लिए नहीं है। बस एक नया बनाना सुनिश्चित करें। यदि आप प्रोफ़ाइल करेंगे तो ही पता चलेगा कि क्या इससे कोई फ़र्क पड़ता है।
ब्रायन नील

1
sgreeve, ब्रायन, यह सही है। ध्यान दें, हालांकि, ऊपर दिए गए litb का तरीका std के उपयोग की आवश्यकता है :: समाप्त होता है। यह बफ़र को पुन: उपयोग करता है, लेकिन आपको स्ट्रिंग के साथ सामान्य रूप से अलग कोड बनाता है (आमतौर पर आप एसटीडी का उपयोग नहीं करते हैं :: छोर)।
डिएगो सेविला

2

यदि आप बफर को इस तरह से साफ़ करने जा रहे हैं, जिससे यह पहली बार उपयोग होने से पहले ही साफ़ हो जाएगा, तो आपको पहले w / 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
    }
};

मैं VS2012 पर असफल व्यवहार नहीं देख रहा हूं। इसके अलावा, बुला clearहोगा कारणfailbit सेट होने के लिए करता है, तो धारा खाली है। seekpयदि कोई धारा मौजूद नहीं है तो बस कॉलिंग को वापस लौटना चाहिए।
जोनाथन एमई

0

तुम नहीं। स्पष्टता के लिए दो अलग-अलग नामित धाराओं का उपयोग करें और अनुकूलन संकलक को यह पता लगाने दें कि यह पुराने का पुन: उपयोग कर सकता है।


4
उपयोग के मामले पर विचार करें जहां कोड इनपुट डेटा पर लूपिंग कर रहा है, एक ostringstream(डेटा रीड के आधार पर) को लिख रहा है और फिर ostringstreamसमय-समय पर कहीं में निर्मित स्ट्रिंग को लिखना है (जैसे एक निश्चित चरित्र अनुक्रम पढ़ने के बाद) और शुरू एक नए तार का निर्माण।
आंद्रे होल्जनर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.