2012-11-26 21 views
12

पर विचार करें:अंतर << a_value

std::string  s_a, s_b; 

std::stringstream ss_1, ss_2; 

// at this stage: 
//  ss_1 and ss_2 have been used and are now in some strange state 
//  s_a and s_b contain non-white space words 

ss_1.str(std::string()); 
ss_1.clear(); 

ss_1 << s_a; 
ss_1 << s_b; 

// ss_1.str().c_str() is now the concatenation of s_a and s_b, 
//     <strike>with</strike> without space between them 

ss_2.str(s_a); 
ss_2.clear(); 

// ss_2.str().c_str() is now s_a 

ss_2 << s_b; // line *** 

// ss_2.str().c_str() the value of s_a is over-written by s_b 
// 
// Replacing line *** above with "ss_2 << ss_2.str() << " " << s_b;" 
//     results in ss_2 having the same content as ss_1. 

सवाल:

  1. क्या stringstream.str (a_value) के बीच का अंतर है, और स्ट्रिंगस्ट्रीम < < a_value; और, विशेष रूप से, पहले क्यों < < के माध्यम से concatenation की अनुमति देता है लेकिन दूसरा करता है?

  2. क्यों ss_1 स्वचालित रूप से s_a और s_b के बीच सफेद स्थान प्राप्त किया था, लेकिन हम स्पष्ट रूप से लाइन है कि लाइन *** बदल सकते में सफेद स्थान जोड़ने की जरूरत है: ss_2 << ss_2.str() << " " << s_b;?

+0

आप में उदाहरण के लिए, आपके तार खाली हैं। S_a और s_b' के बीच स्वचालित रूप से 'व्हाइट-स्पेस' प्राप्त करने का क्या मतलब है? –

+0

@JesseGood '// s_a और s_b में गैर-सफेद स्पेस शब्द ' –

उत्तर

4

आ रही समस्या का क्योंकि std::stringstreamios_base::openmode mode = ios_base::in|ios_base::out के साथ डिफ़ॉल्ट जो एक गैर जोड़कर विधा है द्वारा निर्मित किया गया है।

आप यहाँ उत्पादन मोड में रुचि रखते हैं (यानी: ios_base::openmode mode = ios_base::out)

std::basic_stringbuf::str(const std::basic_string<CharT, Traits, Allocator>& s), दो अलग अलग तरीकों से संचालित openmode पर निर्भर करता है:

  1. mode & ios_base::ate == false: (यानी: गैर appending आउटपुट स्ट्रीम):

    strpptr() == pbase() सेट करेगा, ताकि बाद का आउटपुट पात्रों रों से नकल के ऊपर लिख

  2. mode & ios_base::ate == true: (यानी: जोड़कर आउटपुट स्ट्रीम):

    str, pptr() == pbase() + s.size() सेट हो जाएगा तो यह है कि बाद के उत्पादन रों से नकल अंतिम वर्ण के साथ जोड़ दिया हो जाएगा

(ध्यान दें कि यह मोड जोड़कर ग के बाद से नया है ++ 11)

अधिक जानकारी here मिल सकती है।

आप जोड़कर व्यवहार चाहते हैं, बनाने के अपने stringstreamios_base::ate साथ:

std::stringstream ss(std::ios_base::out | std::ios_base::ate) 

सरल उदाहरण यहाँ एप्लिकेशन:

#include <iostream> 
#include <sstream> 

void non_appending() 
{ 
    std::stringstream ss; 
    std::string s = "hello world"; 

    ss.str(s); 
    std::cout << ss.str() << std::endl; 

    ss << "how are you?"; 
    std::cout << ss.str() << std::endl; 
} 

void appending() 
{ 
    std::stringstream ss(std::ios_base::out | std::ios_base::ate); 
    std::string s = "hello world"; 

    ss.str(s); 
    std::cout << ss.str() << std::endl; 

    ss << "how are you?"; 
    std::cout << ss.str() << std::endl; 
} 

int main() 
{ 
    non_appending(); 
    appending(); 

    exit(0); 
} 

2 अलग अलग तरीकों से जैसा कि ऊपर बताया में हो जाएगा ताकि उत्पादन:

hello world 
how are you? 
hello world 
hello worldhow are you? 
+2

'ओपनमोड' को संशोधित किए बिना ऐसा करने का एक और तरीका है, प्रविष्टि से पहले स्ट्रीम के अंत की तलाश करना है। 'Ss.str (रों); ss.seekp (0, std :: ios_base :: end); एसएस << "आप कैसे हैं?"; ' – Praetorian

+0

धन्यवाद; मामूली चिमटा: non_appending() में, यदि पहली प्रारंभिकता अधिक हो जाती है, तो कहें, std::string s = "A very long hello world!"; तब आउटपुट की दूसरी पंक्ति होगी: "आप कैसे हैं? हैलो वर्ल्ड!" – user1823664

+1

@ user1823664 - यह समझने के लिए कि यहां क्या हो रहा है, आपको यह समझने की आवश्यकता है कि 'स्ट्रिंगस्ट्रीम' 'स्ट्रीमबफर' बफर में स्थितियों को संग्रहीत करने के लिए आंतरिक पॉइंटर्स का उपयोग करता है। 'str()' इन 'पॉइंटर्स का उपयोग एक नया' std :: string' बनाने के लिए करता है - और 'egptr' या' pptr' कहां पर निर्भर करता है, आपको इनसे निर्मित एक स्ट्रिंग मिल जाएगी। –

4

सुझाएँ आप stringstream संदर्भ पढ़ें: http://en.cppreference.com/w/cpp/io/basic_stringstream

std::stringstream::str() धारा में

operator<< आवेषण डेटा अंतर्निहित स्ट्रिंग की सामग्री को बदलता है।

+0

अभी भी यह नहीं बताता है कि' str() 'के बाद' << 'का व्यवहार क्यों होता है, जब तक कि मैं –

+2

कुछ गलत तरीके से पढ़ रहा हूं, दूसरी बात यह है कि' str() ', थथिंग सिंक से बाहर हो जाती है। उदाहरण के लिए, एक नए उदाहरण पर 'str()' का उपयोग करके, 'ऑपरेटर <<' के बाद शुरुआत में दूसरा भाग डालेगा, पहले भाग को ओवरराइट कर देगा। http://ideone.com/OPR9Ps – chris

+1

वह पूछ रहा है कि सामग्री को प्रतिस्थापित करने के लिए 'str' का उपयोग करके ** ऑपरेटर <<' ** को कॉल करने के बाद ** ** अंत में ** संलग्न नहीं है - और उत्तर इसलिए है क्योंकि ' ओपनमोड' में 'एटी' सेट नहीं है –