इंटरनेट पर कई पोस्ट हैं जो सुझाव देते हैं कि आपको std::vector<unsigned char>
या बाइनरी डेटा के समान कुछ उपयोग करना चाहिए।क्या मैं सी ++ 11 में बाइनरी डेटा के लिए सुरक्षित रूप से std :: स्ट्रिंग का उपयोग कर सकता हूं?
लेकिन इसके लिए मैं std::basic_string
संस्करण को अधिक पसंद करता हूं, क्योंकि यह कई सुविधाजनक स्ट्रिंग मैनिपुलेशन फ़ंक्शंस प्रदान करता है। और AFAIK, सी ++ 11 के बाद, मानक गारंटी देता है कि प्रत्येक ज्ञात सी ++ 03 कार्यान्वयन पहले से ही क्या करता है: std::basic_string
इसकी सामग्री को स्मृति में संगत रूप से संग्रहीत करता है।
पहली नज़र में, std::basic_string<unsigned char>
एक अच्छा विकल्प हो सकता है।
मैं std::basic_string<unsigned char>
का उपयोग नहीं करना चाहता, हालांकि, लगभग सभी ऑपरेटिंग सिस्टम केवल char*
स्वीकार करते हैं, जिससे एक स्पष्ट कलाकार आवश्यक होता है। इसके अलावा, स्ट्रिंग अक्षर const char*
हैं, इसलिए मुझे हर बार जब मैंने बाइनरी स्ट्रिंग को स्ट्रिंग अक्षर दिया था, तो मुझे const unsigned char*
पर एक स्पष्ट कलाकार की आवश्यकता होगी, जिसे मैं टालना चाहूंगा। साथ ही, फाइलों या नेटवर्किंग बफर से पढ़ने और लिखने के लिए कार्य समान रूप से char*
और const char*
पॉइंटर्स स्वीकार करते हैं।
यह std::string
छोड़ देता है, जो मूल रूप से std::basic_string<char>
के लिए टाइप किया गया है।
द्विआधारी डेटा के लिए std::string
का उपयोग करने वाला एकमात्र संभावित शेष मुद्दा (जिसे मैं देख सकता हूं) std::string
char
(जिसे हस्ताक्षर किया जा सकता है) का उपयोग करता है।
char
, signed char
, और unsigned char
तीन विभिन्न प्रकार हैं और char
या तो अहस्ताक्षरित या हस्ताक्षर किए जा सकता है।
तो, जब 11111111b
का एक वास्तविक बाइट मूल्य std::string:operator[]
चार के रूप में से दिया जाता है, और आप अपने मूल्य जाँच करना चाहते हैं, अपने मूल्य किया जा सकता है या तो 255
(यदि char
अहस्ताक्षरित है) या यह "कुछ नकारात्मक" हो सकता है (अगर char
आपके नंबर के प्रतिनिधित्व के आधार पर हस्ताक्षरित है)।
इसी प्रकार, यदि आप स्पष्ट रूप से एक std::string
करने के लिए वास्तविक बाइट मूल्य 11111111b
संलग्न करना चाहते हैं, बस जोड़कर (char) (255)
कार्यान्वयन से परिभाषित (और यहां तक कि एक संकेत उठाना) यदि char
हस्ताक्षरित किया गया है और हो सकता है एक अतिप्रवाह में int
char
को बातचीत के परिणाम ।
तो, क्या इसके आसपास एक सुरक्षित तरीका है, जो std::string
बाइनरी-सुरक्षित बनाता है?
§3.10/15 राज्यों:
एक कार्यक्रम निम्नलिखित प्रकार व्यवहार अपरिभाषित है में से एक के अलावा अन्य के glvalue के माध्यम से एक वस्तु की संग्रहीत मूल्य तक पहुँचने के लिए प्रयास करता है:
- [...]
- एक प्रकार है कि हस्ताक्षर किए या अहस्ताक्षरित प्रकार वस्तु के गतिशील प्रकार के अनुरूप,
- [...]
- एक चार या हस्ताक्षरित चार प्रकार।
अगर मैं इसे सही ढंग से समझ, उपयोग और std::string
की सामग्री में हेरफेर करने के unsigned char*
सूचक का उपयोग कर अनुमति देने के लिए लगता है और यह भी अच्छी तरह से परिभाषित बनाता कौन सा,। यह सिर्फ , एक unsigned char
रूप बिट पैटर्न reinterprets, किसी भी बदलाव या जानकारी हानि के बिना उत्तरार्द्ध अर्थात् क्योंकि में एक char
, signed char
, और unsigned char
मूल्य प्रतिनिधित्व के लिए इस्तेमाल किया जाना चाहिए सभी बिट्स।
मैं तो char
ही की signedness की [0, 255]
रेंज में उपयोग करने के लिए और परिवर्तन बाइट मूल्यों, एक अच्छी तरह से परिभाषित और पोर्टेबल ढंग से, चाहे एक साधन के रूप std::string
की सामग्री के इस unsigned char*
व्याख्या इस्तेमाल कर सकते हैं।
यह संभावित रूप से हस्ताक्षरित char
से उत्पन्न होने वाली किसी भी समस्या का समाधान करना चाहिए।
क्या मेरी धारणाएं और निष्कर्ष सही हैं?
इसके अलावा, unsigned char*
समान पैटर्न की व्याख्या (यानी 11111111b
या 10101010b
) सभी कार्यान्वयन पर समान होने की गारंटी है? अलग-अलग रखें, क्या मानक गारंटी है कि "unsigned char
की आंखों को देखकर", वही बिट पैटर्न हमेशा एक ही संख्यात्मक मान की ओर जाता है (मानते हैं कि बाइट में बिट्स की संख्या समान है)?
कर सकते हैं मैं इस प्रकार सुरक्षित रूप से (अर्थात, के बिना किसी भी अपरिभाषित या कार्यान्वयन से परिभाषित व्यवहार) सी ++ 11 में भंडारण और बाइनरी डेटा जोड़ तोड़ के लिए std::string
का उपयोग करें?
जब आप लिखते हैं, "लगभग सभी मानक लाइब्रेरी फ़ंक्शन केवल char * स्वीकार करते हैं," क्या आप समझा सकते हैं कि आप कौन से लाइब्रेरी फ़ंक्शंस का उपयोग करना चाहते हैं? यदि आप सी ++ मानक लाइब्रेरी से चिपके रहते हैं, तो 'std :: basic_string' सदस्य फ़ंक्शंस आपके द्वारा प्रदान किए जाने वाले वास्तविक 'CharT' प्रकार को प्रतिबिंबित करेगा। उदाहरण: 'std :: basic_string :: c_str()' रिटर्न 'कॉन्स्टिनेटेड char *'। आईओ के संदर्भ में, यदि आप 'हस्ताक्षरित चार' पर एक आईट्रीम या ओस्ट्रीम टेम्पलेट कर सकते हैं, तो सब कुछ अंतःक्रिया करेगा। –
NicholasM
आप केवल 'std :: basic_string' का व्युत्पन्न वर्ग बना सकते हैं और इसके लिए कुछ अंतर्निहित बना सकते हैं। –
Zaffy
बस एक वेक्टर का उपयोग करें। आप इसके साथ कुछ भी कर सकते हैं कि आप एक स्ट्रिंग के साथ कर सकते हैं। – jrok