2010-05-16 3 views
31

नियमित सी तारों के लिए, एक शून्य चरित्र '\0' डेटा के अंत का प्रतीक है।क्या एक std :: स्ट्रिंग में एम्बेडेड नल शामिल हो सकते हैं?

std::string के बारे में क्या, क्या मेरे पास एम्बेडेड नल वर्णों के साथ एक स्ट्रिंग हो सकती है?

+1

देखें [std :: स्ट्रिंग नल वर्णों वाले डेटा के बराबर है?] (Http://stackoverflow.com/questions/1534335/stdstring-equivalent-for-data-with-null-characters) –

उत्तर

32

हाँ आप अपने std::string में एम्बेडेड नल रख सकते हैं।

उदाहरण:

std::string s; 
s.push_back('\0'); 
s.push_back('a'); 
assert(s.length() == 2); 

नोट: std::string के c_str() सदस्य हमेशा लौट आए चार बफर करने के लिए एक अशक्त चरित्र में संलग्न कर देगा; हालांकि, std::string का data() सदस्य लौटे हुए चार बफर में एक शून्य चरित्र जोड़ सकता है या नहीं।

बाहर देखने के लिए के लिए है आरएचएस पर एक char* साथ operator+= का उपयोग नहीं करने के लिए ऑपरेटर + =

एक बात से सावधान रहें। यह केवल शून्य चरित्र तक जोड़ देगा।

उदाहरण के लिए:

std::string s = "hello"; 
s += "\0world"; 
assert(s.length() == 5); 

सही तरीका:

std::string s = "hello"; 
s += std::string("\0world", 6); 
assert(s.length() == 11); 

बाइनरी डेटा अधिक std :: वेक्टर उपयोग करने के लिए आम भंडारण

आम तौर पर इसे और अधिक करने के लिए std::vector उपयोग करने के लिए आम है मनमाने ढंग से बाइनरी डेटा स्टोर करें।

std::vector<char> buf; 
buf.resize(1024); 
char *p = &buf.front(); 

यह शायद ज्यादा आम है के बाद से std::string के data() और c_str() सदस्यों स्थिरांक संकेत लौट इतना स्मृति परिवर्तनीय नहीं है। & buf.front() के साथ आप सीधे बफर की सामग्री को संशोधित करने के लिए स्वतंत्र हैं।

+2

सी ++ 9x 'और s.front() 'में भी संशोधित बफर पर इंगित करने के लिए संशोधित और गारंटीकृत है। हालांकि सी ++ 03 में ऐसी कोई गारंटी नहीं थी, वहां कोई ज्ञात सी ++ कार्यान्वयन नहीं है जिसके लिए यह अभ्यास में सही नहीं था (जो आंशिक रूप से इसे सी ++ 0x में इतनी जल्दी क्यों जोड़ा गया था)। –

+6

ध्यान दें कि सी ++ 11, '.c_str()' और '.डेटा' समानार्थी हैं। विशेष रूप से, इसका मतलब है कि '.data' द्वारा लौटाई गई स्ट्रिंग में एक शून्य टर्मिनेटर संलग्न होना चाहिए। – nneonneo

+0

@PavelMinaev: मुझे लगता है कि "सी ++ 9एक्स" "सी ++ 0x" के लिए एक टाइपो था (जो आपकी टिप्पणी पोस्ट करने के कुछ समय बाद सी ++ 11 बन गया)। –

-1

हाँ यह मान्य है।

आपके पास स्ट्रिंग के बीच में एक शून्य चरित्र हो सकता है।

हालांकि, अगर आप एसी स्ट्रिंग समारोह के साथ बीच में एक अशक्त चरित्र के साथ एक std :: स्ट्रिंग का उपयोग अपने अपरिभाषित व्यवहार शहर में - और कोई नहीं बनना चाहता है !!!:

int n = strlen(strWithNullInMiddle.c_str()); // Boom!!! 
+12

'strlen' बस पहले शून्य से पहले अक्षर की संख्या वापस करें। यह अप्रत्याशित व्यवहार हो सकता है, लेकिन यह अपरिभाषित नहीं है। –

8

हां। लाभ के साथ एक std :: स्ट्रिंग सिर्फ vector<char> है।

हालांकि, कुछ है कि .c_str() कॉल और 0.

+0

जैसा कि मैंने हाल ही में सीखा है, पहला सत्य नहीं है। वेक्टर का स्वैप सामग्री के पुनरावृत्तियों और संदर्भों को संरक्षित करता है, स्ट्रिंग जरूरी नहीं है। http://stackoverflow.com/questions/25201758/stringswap-complexity-under-visual-studio – Notinlist

+0

@ नोटिनलिस्ट: इसका एक अलग नाम भी है! ओह डरावनी –

1

आप कर सकते हैं पर रुक जाता है करने के लिए इस तरह के एक जानवर गुजर के बारे में सावधान रहना होगा, लेकिन तुम क्यों चाहेगा? एक std :: स्ट्रिंग में एनयूएल एम्बेड करना केवल परेशानी के लिए पूछ रहा है, क्योंकि जिन कार्यों को आप std :: स्ट्रिंग पास करते हैं, वे बहुत सी अच्छी तरह से इसका उपयोग कर सकते हैं c_str() सदस्य, और अधिकांश मान लेंगे कि पहला एनयूएल स्ट्रिंग के अंत को इंगित करता है। इसलिए यह करना एक अच्छा विचार नहीं है। यह भी ध्यान रखें कि यूटीएफ -8 में, केवल '\ 0' के परिणामस्वरूप 0 होगा, इसलिए i18n उद्देश्यों के लिए, एनयूएल एम्बेड करने के लिए कोई औचित्य नहीं है।

+0

यह बताने के लिए धन्यवाद कि क्यों * नहीं * ऐसा करना है। – Snoopy

+1

नहीं, यह मूर्खतापूर्ण है। "' Std :: string' की कार्यक्षमता की पूरी श्रृंखला का उपयोग न करें, क्योंकि आप _might_ को 'c_str() 'के परिणामस्वरूप सी-स्ट्रिंग फ़ंक्शंस के बिना पास गुजरने के परिणाम पास करते हैं", वास्तव में? खैर, अगर आप ऐसा कभी नहीं करते हैं, तो आप ठीक होंगे ... –

संबंधित मुद्दे