2011-03-16 15 views
7

यह क्यों है कि आप एक std :: basic_string में '\ 0' char डाल सकते हैं और .length() विधि अप्रभावित है लेकिन यदि आप char_traits<char>::length(str.c_str()) पर कॉल करते हैं तो आपको स्ट्रिंग की लंबाई मिलती है पहले '\ 0' चरित्र तक?शून्य वर्णों के साथ STL basic_string लंबाई

उदा

string str("abcdefgh"); 
cout << str.length(); // 8 
str[4] = '\0'; 
cout << str.length(); // 8 
cout << char_traits<char>::length(str.c_str()); // 4 

उत्तर

17

महान प्रश्न!

कारण यह है कि एक सी-शैली स्ट्रिंग को बाइट्स के अनुक्रम के रूप में परिभाषित किया जाता है जो एक शून्य बाइट के साथ समाप्त होता है। जब आप C++ std::string से सी-स्टाइल स्ट्रिंग प्राप्त करने के लिए .c_str() का उपयोग करते हैं, तो आप इसके बाद एक नल बाइट के साथ सी ++ स्ट्रिंग स्टोर अनुक्रम वापस प्राप्त कर रहे हैं। जब आप इसे strlen में पास करते हैं, तो यह बाइट्स तक स्कैन करेगा जब तक कि यह एक शून्य बाइट हिट नहीं करता है, फिर रिपोर्ट करें कि इससे पहले कितने अक्षर मिले। यदि string में एक शून्य बाइट है, तो strlen एक मान की रिपोर्ट करेगा जो स्ट्रिंग की पूरी लंबाई से छोटी है, क्योंकि यह स्ट्रिंग के वास्तविक अंत को मारने से पहले रुक जाएगा।

एक महत्वपूर्ण विवरण यह है कि strlen और char_traits<char>::length समान कार्य नहीं हैं। हालांकि, char_traits<charT>::length के लिए सी ++ आईएसओ कल्पना (§ 21.1.1) का कहना है char_traits<charT>::length(s) रिटर्न कि छोटी से छोटीi ऐसी है कि char_traits<charT>::eq(s[i], charT()) सच है। char_traits<char> के लिए, eq समारोह सिर्फ लौटाता है यदि दो अक्षर एक == तुलना कर रही है, और लेखन char() एक अशक्त बाइट का उत्पादन द्वारा एक चरित्र का निर्माण करके बराबर हैं, और इसलिए यह कह "जहाँ स्ट्रिंग में पहले अशक्त बाइट है के बराबर है? " यह अनिवार्य रूप से strlen काम करता है, हालांकि दोनों तकनीकी रूप से अलग-अलग कार्य हैं।

ए सी ++ std::string, हालांकि, यह "पात्रों के मनमाना अनुक्रम" की एक और सामान्य धारणा है। इसके कार्यान्वयन के विवरण बाहरी दुनिया से छिपे हुए हैं, हालांकि यह शायद शुरुआत से और पॉइंटर या पॉइंटर और लंबाई से प्रतिनिधित्व करता है। चूंकि यह प्रतिनिधित्व इस बात पर निर्भर नहीं है कि कौन से पात्रों को संग्रहीत किया जा रहा है, std::string से इसकी लंबाई के लिए पूछें कि वास्तव में वे वर्ण क्या हैं, इस पर ध्यान दिए बिना कि कितने अक्षर हैं।

आशा है कि इससे मदद मिलती है!

+1

+1, और मैं बस जोड़ दूंगा कि यदि आप वास्तव में आंतरिक नल बाइट चाहते हैं, तो मेरा मानना ​​है कि कोई 'basic_string <> :: डेटा() 'सदस्य फ़ंक्शन का उपयोग कर सकता है। – dappawit

+5

@ दप्पाविट- यह नहीं है कि 'c_str() 'शून्य बाइट्स निकालता है और वह' डेटा() 'उन्हें छोड़ देता है; बल्कि, दोनों में उनके पास शून्य बाइट्स हैं, और 'c_str()' गारंटी देता है कि अंत में एक शून्य बाइट है और 'डेटा' नहीं है। मुद्दा यह है कि स्ट्रिंग के लिए आंतरिक उन बाइट्स को उन कार्यों द्वारा व्याख्या किया जाता है जिनका उपयोग सी-शैली स्ट्रिंग कार्यान्वयन के लिए किया जाता है। – templatetypedef

+0

आह! आपने वह हिस्सा जोड़ा जो मैं उत्तर में डाल रहा था। – mkb

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