2014-07-13 5 views
7

मैं एक पोर्टेबल लाइब्रेरी लिख रहा हूं जो फाइलों और निर्देशिकाओं से संबंधित है। मैं अपने इनपुट (निर्देशिका पथ) और आउटपुट (फ़ाइल पथ) के लिए यूटीएफ -8 का उपयोग करना चाहता हूं। समस्या यह है कि, विंडोज़ मुझे यूटीएफ -16-जो-इस्तेमाल-टू-बी-यूसीएस -2, और कोडपेज के बीच एक विकल्प देता है। इसलिए मुझे अपने सभी यूटीएफ -8 तारों को यूटीएफ -16 में परिवर्तित करना है, उन्हें WinAPI में पास करना है, और परिणामों को वापस यूटीएफ -8 में परिवर्तित करना है। सी ++ 11 केवल <locale> लाइब्रेरी प्रदान करने के लिए प्रतीत होता है, जो मुझे समझा जाता है, छोड़कर, पूर्वनिर्धारित विशेषज्ञता में से कोई भी यूटीएफ -8 को आंतरिक (यानी मेरी तरफ) कोडिंग के रूप में उपयोग नहीं करता है - निकटतम यूटीएफ -16-टू- यूटीएफ -8, जो है जो मैं चाहता हूं के विपरीत विपरीत है। तो यहां पहला सवाल है:यूटीएफ -8 का उपयोग तारों के आंतरिक प्रतिनिधित्व के रूप में करने के लिए सी ++ 11 लोकेल सुविधाओं का उपयोग कैसे करें?

1) WinCI कॉल के लिए मेरे यूटीएफ -8 तारों को यूटीएफ -16 में परिवर्तित करने के लिए कोडेकवैट चीज़मैजिज का उपयोग कैसे करें, और यूटीएफ -16 यूटीएफ -8 के परिणाम वापस आ जाए?

एक और समस्या: मैं लिनक्स को भी लक्षित कर रहा हूं। लिनक्स पर, कई अलग-अलग स्थानों के लिए बहुत अच्छा समर्थन है - और मैं कोई अलग नहीं होना चाहता हूं। उम्मीद है कि हर कोई अपनी लिनक्स मशीनों पर यूटीएफ -8 का उपयोग करेगा, लेकिन इसकी कोई सख्त गारंटी नहीं है। तो मैंने सोचा कि उपर्युक्त विंडोज-विशिष्ट व्यवहार को विस्तारित करना और हमेशा यूटीएफ -8-टू-सिस्टम-लोकेल-कोडिंग करना एक अच्छा विचार होगा। सिवाय इसके कि मुझे नहीं लगता कि वर्तमान सिस्टम एन्कोडिंग प्राप्त करने के लिए सी ++ 11 की <locale> लाइब्रेरी में कोई तरीका है! डिफ़ॉल्ट std :: लोकेल कन्स्ट्रक्टर निर्दिष्ट-द्वारा-स्वयं लोकेल बनाता है, और यदि मैं ऐसा नहीं करता, तो यह क्लासिक "सी" लोकेल लौटाता है। और मुझे कोई अन्य गेटर्स नहीं है जो मुझे पता है। तो यहां दूसरा प्रश्न है:

2) वर्तमान सिस्टम लोकेल का पता कैसे लगाएं? <locale> में कुछ? हो सकता है कि कुछ मानक सी लाइब्रेरी फ़ंक्शन, या (कम पोर्टेबल लेकिन इस मामले में ठीक है) POSIX API में कुछ?

+0

: दूसरा पैराग्राफ है ** नहीं ** पहला सवाल का हिस्सा !!! की [स्ट्रिंग, u16string और u32string के बीच कन्वर्ट] – Xirdus

+2

संभव डुप्लिकेट (http://stackoverflow.com/questions/7232710/convert-between-string-u16string-u32string) – tclamb

+0

@tclamb नहीं वास्तव में एक नकली है, लेकिन उस सवाल का जवाब होगा मेरे लिए सहायक हो। लिंक के लिए धन्यवाद। लेकिन सवाल 2) अभी भी खड़ा है। 'Std :: स्थान (" ") का नाम()': – Xirdus

उत्तर

-1

मानक पुस्तकालय में इन सुविधाओं का डिज़ाइन मानता है कि मल्टीबाइट वर्ण एन्कोडिंग (जैसे यूटीएफ -8) का उपयोग बाहरी भंडारण (यानी डिस्क पर फ़ाइलों में बाइट अनुक्रम) के लिए किया जाता है और स्मृति में सभी वर्ण आकार में समान हैं। यह std::basic_string<T>::operator[] जैसी चीजें मानक द्वारा लगाए गए प्रदर्शन बाधाओं के अनुरूप तरीके से व्यवहार कर सकती हैं। इसलिए जब आप यूटीएफ -8 या कुछ अन्य एमबीसीएस (जापानी के लिए उन लोगों) में एन्कोड किए गए फ़ाइलों का उपयोग कर सकते हैं, तो स्मृति में आपके तार char, char16_t, char32_t या wchar_t होना चाहिए।

यही कारण है कि आप मानक पुस्तकालय में एक मैच नहीं ढूंढ रहे हैं जिसके लिए आप करना चाहते हैं क्योंकि स्मृति में तारों को यूटीएफ -8 में संग्रहीत करने का इरादा नहीं है। यह जावा जैसी अन्य भाषाओं के समान है, जहां डिस्क पर डेटा बाइट्स की धारा के रूप में व्याख्या किया जाता है और उन्हें तारों में बदलने के लिए आपको बाइट स्ट्रीम के अपेक्षित वर्ण एन्कोडिंग को कुछ घटक बताने की आवश्यकता होती है। कुछ ऑपरेटिंग सिस्टम यूटीएफ -8 स्ट्रिंग को argv[] में रख सकते हैं, लेकिन यह गैर-मानक है। यही कारण है कि विंडोज पर WinMain के लिए यूनिकोड सक्षम प्रविष्टि बिंदु NULwchar_t पर पॉइंटर समाप्त कर दिया गया है और char* एक यूटीएफ -8 एन्कोडेड स्ट्रिंग को इंगित नहीं करता है।

आईबीएम की International Components for Unicode लाइब्रेरी उन घटकों का एक पूरा सेट प्रदान करती है जो पूरक हैं, और सी ++ मानक पुस्तकालय के साथ काम करने के लिए डिज़ाइन करते हैं। मैं उनके कोड रूपांतरण सुविधाओं को देखता हूं। जबकि मानक कोड रूपांतरण के लिए <locale> में सुविधाओं को परिभाषित करता है, यह यूटीएफ -8 से char16_t, char32_t, या wchar_t से मानचित्र करने के लिए कोड रूपांतरण सुविधा के किसी भी अस्तित्व की गारंटी नहीं देता है। यदि ऐसी कोई चीज़ मौजूद है, तो आप इसे केवल अपने कार्यान्वयन के विवरण के आधार पर प्राप्त करेंगे। आईसीयू लाइब्रेरी किसी भी सी ++ कार्यान्वयन के लिए पोर्टेबल रूप से इस कार्यक्षमता प्रदान करती है। यह अच्छी तरह से समर्थित है और अच्छी तरह से उपयोग किया जाता है और यूटीएफ -8 स्ट्रिंग्स को उचित व्यापक-char स्ट्रिंग में डीकोड करने की संभावना नहीं है।

कोनराड ने एक टिप्पणी में यूटीएफ -8 कहीं भी घोषणापत्र का उल्लेख किया।यह एक दिलचस्प पढ़ा गया था और वे आपको ऊपर बताई गई समस्याओं का समाधान पाने के लिए Boost.Nowide लाइब्रेरी (आधिकारिक तौर पर अभी तक बूस्ट का हिस्सा नहीं) पर इंगित करते हैं।

कृपया ध्यान दें कि मेरा उत्तर बस जिस तरह से मौजूदा सी ++ std::basic_string<T> काम की तरह मानक पुस्तकालय वर्गों का वर्णन है। यह यूटीएफ -8, यूनिकोड, या कुछ और के खिलाफ सलाह नहीं है। घोषणापत्र उद्धृत मेरे साथ सहमत है कि ये चीजें बस इस तरह से काम नहीं करती हैं और यदि आप कहीं भी यूटीएफ -8 का उपयोग करना चाहते हैं, तो आपको कुछ और चाहिए।

करने के लिए जो कोई भी मेरी रोलबैक से पहले इस सवाल का संपादित
+1

"स्मृति में तारों को यूटीएफ -8 में संग्रहीत करने का इरादा नहीं है। "- नहीं, तुम यहाँ गलत हो। [यूटीएफ -8 कहीं भी घोषणापत्र] (http://www.utf8everywhere.org/) आपके साथ असहमत है, और वह दस्तावेज़ कई डेवलपर्स द्वारा एक बहुत अच्छा सारांश के रूप में देखा जाता है। संक्षेप में, 'std :: string' यूटीएफ -8 के लिए एक ठीक कंटेनर है, और मानक पुस्तकालय अंतर्निहित चरित्र प्रकार के बावजूद यूनिकोड के साथ काम करने के लिए पर्याप्त सुविधाएं प्रदान नहीं करता है। –

+0

'std :: string' बहु-बाइट वर्ण सेट के लिए डिज़ाइन नहीं किया गया है, यह बस इतना आसान है। आप उस डिज़ाइन से असहमत हो सकते हैं और एक वैकल्पिक स्ट्रिंग क्लास बना सकते हैं जो एमबीसीएस जागरूक है, लेकिन 'std :: string' बस उस तरह से काम नहीं करता है। मानक पुस्तकालय में सब कुछ मानता है कि सभी पात्रों को बिट्स की संख्या में एन्कोड किया गया है। जब मैं कहता हूं कि "स्मृति में तारों को यूटीएफ -8 में संग्रहीत करने का इरादा नहीं है", तो मैं विशेष रूप से 'std :: string',' std :: wstring', और अंडरलिंग टेम्पलेट वर्ग 'std के लिए टाइपपीफ का जिक्र कर रहा हूं: : basic_string '। "सबस्ट्रिंग विधियां खुशी से अमान्य स्ट्रिंग लौटाएंगी" – legalize

+1

मानक लाइब्रेरी टेक्स्ट से निपटने में बस कमी है, इसका उपयोग इसके डिजाइन से बहस करने का कोई फायदा नहीं है। 'std :: string' एक बाइट स्टोरेज है, एक टेक्स्ट स्टोरेज नहीं। लेकिन यूटीएफ -8 एन्कोडेड टेक्स्ट के लिए एक पारदर्शी भंडारण के रूप में 'std :: string' का उपयोग करने के लिए पूरी तरह स्वीकार्य है, जब तक कि आप इसे एन्कोडिंग अज्ञेय तरीके से संचालित नहीं करते हैं। इसके लिए आपको एक लाइब्रेरी (जैसे आईसीयू, या [ओगोनिक] (http://flamingdangerzone.com/ogonek/) की आवश्यकता होगी, जिसमें असीमित निचला सी ++ इंटरफेस है लेकिन अभी भी अपूर्ण है)। –

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

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