2010-07-28 18 views
8

मैं विज़ुअल सी में एक multibyte-चरित्र स्ट्रिंग के बाइट आकार कैसे प्राप्त करूं? क्या कोई कार्य है या क्या मुझे पात्रों को गिनना है?कैसे multibyte स्ट्रिंग के बाइट आकार पाने के लिए

या, अधिक सामान्य, मैं एक टीसीएचएआर स्ट्रिंग का सही बाइट आकार कैसे प्राप्त करूं?

समाधान:

_tcslen(_T("TCHAR string")) * sizeof(TCHAR) 

संपादित करें:
मैं केवल अशक्त-समाप्त तार के बारे में बात कर रहा था।

+3

स्ट्रिंग के बाइट्स में आकार की गणना करने के लिए आपका कोड सही है। कथन "के लिए काम करता है ... char और wchar_t ... लेकिन मल्टीबाइट-कैरेक्टर स्ट्रिंग्स के लिए नहीं" हालांकि उलझन में है। – Thanatos

+0

तो मल्टीबाइट-कैरेक्टर स्ट्रिंग में नल बाइट्स नहीं हैं? – flacs

+0

@ टिलका: वे कर सकते थे, लेकिन आपको किसी अन्य फैशन में लंबाई जानने की आवश्यकता होगी, जैसे स्ट्रिंग के साथ आने वाले पूर्णांक में इसे संग्रहीत करना। नल को तारों को समाप्त कर दिया जाता है, जो कि आम तौर पर मुठभेड़ करते हैं (और क्या _tcslen, strlen, आदि की आवश्यकता होती है), नल टर्मिनेटर को छोड़कर, शून्य बाइट्स नहीं होते हैं। – Thanatos

उत्तर

3

According to MSDN, _tcslenstrlen से संबंधित है जब _MBCS परिभाषित किया गया है। strlen स्ट्रिंग में बाइट्स की संख्या वापस आ जाएगी। यदि आप _tcsclen का उपयोग करते हैं जो _mbslen से मेल खाता है जो multibyte वर्ण की संख्या देता है।

इसके अलावा, मल्टीबाइट स्ट्रिंग्स (AFAIK) में एम्बेडेड नल, नहीं हैं।

मैं पहली जगह में एक मल्टीबाइट एन्कोडिंग के उपयोग पर सवाल उठाऊंगा, हालांकि ... जब तक आप एक विरासत ऐप का समर्थन नहीं कर रहे हैं, तो यूनिकोड पर मल्टीबाइट चुनने का कोई कारण नहीं है।

+1

यूटीएफ -8 तारों में एम्बेडेड नल शामिल नहीं होते हैं (विशेष रूप से: केवल 0 बाइट एक ही स्थान होता है जो 0 कोड बिंदु का प्रतिनिधित्व करता है, इसलिए यदि यह आपका टर्मिनेटर है तो आप बाइट-वार के लिए खोज सकते हैं)। मुझे यकीन नहीं है कि यूटीएफ -16 को इस संदर्भ में "मल्टीबाइट एन्कोडिंग" माना जाता है, लेकिन इसमें निश्चित रूप से 0 * बाइट्स * हो सकते हैं, केवल 0 डबल-बाइट्स नहीं। मुझे लगता है कि शिफ्ट-जेआईएस 0 बाइट्स का उपयोग नहीं करता है, जबकि एन्कोडिंग 0 को दुनिया में बहुत सारे एन्कोडिंग, लेकिन मुझे यकीन नहीं है कि विंडोज लोकेशंस के भीतर क्या संभव है ... –

+1

यह थोड़ा उलझन में है: यूटीएफ -8 तारों में नल शामिल हो सकते हैं , * यदि * आप शून्य टर्मिनेटर के अलावा किसी अन्य चीज़ में आकार संग्रहित कर रहे हैं। नल टर्मिनेटेड तारों में नल नहीं हो सकते हैं, क्योंकि वे शून्य समाप्त हो जाते हैं। एक शून्य समाप्त यूटीएफ -8 स्ट्रिंग में एक ही कारण के लिए नल शामिल नहीं हो सकते हैं। उस ने कहा, मैं इसे समाप्त करने के अलावा किसी यूटीएफ -8 स्ट्रिंग में शून्य लगाने के किसी भी उपयोगी उद्देश्य के बारे में नहीं सोच सकता। – Thanatos

9

चलो अगर मैं इस स्पष्ट कर सकते हैं देखते हैं:

"मल्टी-बाइट वर्ण स्ट्रिंग" एक अस्पष्ट पद के साथ शुरू करने के लिए है, लेकिन माइक्रोसॉफ्ट की दुनिया में, यह आमतौर पर meants "नहीं ASCII, और नहीं UTF- 16 "। इस प्रकार, आप कुछ वर्ण एन्कोडिंग का उपयोग कर सकते हैं जो 1 बाइट प्रति चरित्र, या 2 बाइट्स, या संभवतः अधिक का उपयोग कर सकता है। जैसे ही आप करते हैं, स्ट्रिंग में वर्णों की संख्या! = स्ट्रिंग में बाइट्स की संख्या।

चलिए यूटीएफ -8 को उदाहरण के रूप में लेते हैं, भले ही इसका उपयोग एमएस प्लेटफॉर्म पर नहीं किया जाता है। चरित्र को स्मृति में "c3 a9" के रूप में एन्कोड किया गया है - इस प्रकार, दो बाइट्स, लेकिन 1 वर्ण। अगर मैं स्ट्रिंग "द" है, यह है:

text: t h é  \0 
mem: 74 68 c3 a9 00 

यह एक "नल समाप्त" स्ट्रिंग, में है कि यह एक अशक्त के साथ समाप्त होता है। कार्यों के एक धसान उस के साथ सौदा करने में मदद करने

struct my_string 
{ 
    size_t length; 
    char *data; 
}; 

... और: यदि हम अपने स्ट्रिंग यह में nulls की अनुमति चाहता था, हम इस तरह के रूप में, कुछ अन्य फैशन में आकार संग्रहीत करने की आवश्यकता होगी। (यह कैसे काम करता है std::string की तरह, काफी मोटे तौर पर है।)

अशक्त-समाप्त तार के लिए, तथापि, strlen() उनके आकार बाइट्स, नहीं अक्षरों में गणना होगी। (वर्णों की गिनती के लिए अन्य फ़ंक्शन हैं) strlen 0 बाइट को देखने से पहले केवल बाइट्स की संख्या की गणना करता है - कुछ भी फैंसी नहीं।

अब, एमएस की दुनिया में "चौड़ा" या "यूनिकोड" स्ट्रिंग यूटीएफ -16 स्ट्रिंग का संदर्भ देता है। उनमें बाइट्स की संख्या में समान समस्याएं हैं! = वर्णों की संख्या। (इसके अलावा: की संख्या बाइट्स/2 = वर्णों की संख्या!) चलो फिर से thé को देखो:

text: t  h  é  \0 
shorts: 0x0074 0x0068 0x00e9 0x0000 
mem: 74 00 68 00 e9 00 00 00 

है कि "द" UTF-16 में, थोड़ा endian में जमा हो जाती है (जो है क्या अपने ठेठ डेस्कटॉप है)। सभी 00 बाइट्स पर ध्यान दें - ये यात्रा ऊपर की ओर बढ़ती हैं। इस प्रकार, हम wcslen पर कॉल करते हैं, जो इसे 2-बाइट short एस के रूप में देखता है, एकल बाइट नहीं।

आखिरकार, आपके पास TCHAR एस है, जो उपरोक्त दो मामलों में से एक है, UNICODE पर निर्भर करता है। _tcslen उचित समारोह (या तो strlen या wcslen) हो जाएगा, और TCHAR या तो char या wchar_t हो जाएगा। TCHAR विंडोज दुनिया में यूटीएफ -16 में जाने के लिए आसान बनाने के लिए बनाया गया था।

+0

"(इसके अलावा: बाइट्स/2 की संख्या! = वर्णों की संख्या)" कैसा है? – flacs

+0

@ टिलका: यूटीएफ -16 एन्कोड वर्णों का यही तरीका है। यूटीएफ -16 65,536 से अधिक विभिन्न पात्रों को एन्कोड कर सकता है, इसलिए यह स्पष्ट होना चाहिए कि 2 बाइट पर्याप्त नहीं हैं। यूटीएफ -16 कई पात्रों को केवल 2 बाइट्स के रूप में एन्कोड करता है, लेकिन कुछ के लिए 4 का उपयोग करना चाहिए, जिसे "सरोगेट जोड़े" के नाम से जाना जाता है (यूटीएफ -16 पर विकिपीडिया का आलेख देखें।) – Thanatos

+0

आह हाँ, मैंने इसे यूसीएस -2 के साथ भ्रमित कर दिया। अच्छा स्पष्टीकरण बीटीडब्ल्यू, लेकिन दूसरा जवाब सीधे बिंदु पर था। – flacs

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