2011-02-14 22 views
5

मैं वर्तमान में स्ट्रिंग के संचालन के लिए std::string और char उपयोग करने वाले ऐप्लिकेशन की देखभाल कर रही हूँ - जो linux पर ठीक है, के बाद से लिनक्स यूनिकोड को नास्तिक है (या तो यह लगता है, मैं वास्तव में नहीं पता है, इसलिए अगर मैं यहां कहानियां कह रहा हूं तो कृपया मुझे सही करें)। यह वर्तमान शैली स्वाभाविक रूप से समारोह/वर्ग घोषणाओं के इस प्रकार की ओर जाता है:यूनिकोड पोर्टेबिलिटी

std::string doSomethingFunkyWith(const std::string& thisdata) 
{ 
    /* .... */ 
} 

हालांकि, अगर thisdata यूनिकोड वर्ण हैं, यह गलत तरीके से खिड़कियों पर प्रदर्शित किया जाएगा, के बाद से std::string विंडोज पर यूनिकोड वर्ण को रोक नहीं सकते।

namespace MyApplication { 
#ifdef UNICODE 
    typedef std::wstring string_type; 
    typedef wchar_t  char_type; 
#else 
    typedef std::string string_type; 
    typedef char   char_type; 
#endif 

    /* ... */ 
    string_type doSomethingFunkyWith(const string_type& thisdata) 
    { 
     /* ... */ 
    } 
} 

यह एक अच्छी अवधारणा खिड़कियों पर यूनिकोड का समर्थन करने के साथ जाने के लिए है:

तो मैं इस अवधारणा को सोचा है?

मेरे वर्तमान टूलचेन में लिनक्स पर जीसीसी/क्लैंग, और विंडोज़ समर्थन के लिए वाइन + मिनजीडब्ल्यू (शराब के माध्यम से भी क्रॉसस्टेस्टिंग भी होता है), यदि यह मायने रखता है।

+1

मुझे लगता है कि यह उचित है। मेरा मानना ​​है कि यह कई पुस्तकालयों जैसे WxWidgets द्वारा लिया गया दृष्टिकोण है। – HighCommander4

+0

हां यह आपके द्वारा उल्लेखित कई पुस्तकालयों, विंडोज़ के लिए किया जाता है। – Marlon

+5

अधिक सटीक, अधिकांश लिनक्स प्रोग्राम यूनिकोड को यूटीएफ -8 के रूप में संभालते हैं, जो 'std :: string' के साथ संगत है। लेकिन इसका मतलब है कि 'आकार() 'और' लंबाई() 'बाइट्स की संख्या देगा, लेकिन जरूरी नहीं कि कोड पॉइंट या ग्लाइफ की संख्या हो। तारों के साथ आप क्या कर रहे हैं इसके आधार पर, आपको अधिक जानकारी की आवश्यकता नहीं हो सकती है। – aschepler

उत्तर

4

मल्टीप्लाफ्फ़्ट मुद्दे इस तथ्य से आते हैं कि कई एन्कोडिंग हैं, और गलत एन्कोडिंग पिक एन्सेडिंग एसेस का कारण बन जाएगा। एक बार जब आप उस समस्या से निपट जाएंगे, तो आप अपने सभी कार्यक्रमों पर std::wstring का उपयोग करने में सक्षम होना चाहिए।

सामान्य कार्यप्रवाह है:

raw_input_data = read_raw_data() 
input_encoding = "???" // What is your file or terminal encoding? 

unicode_data = convert_to_unicode(raw_input_data, input_encoding) 

// Do something with the unicode_data, store in some var, etc. 

output_encoding = "???" // Is your terminal output encoding the same as your input? 
raw_output_data = convert_from_unicode(unicode_data, output_encoding) 

print_raw_data(raw_data) 

अधिकांश यूनिकोड मुद्दों को गलत तरीके से input_encoding और output_encoding के मूल्यों का पता लगाने से आता है। एक आधुनिक लिनक्स वितरण पर यह आमतौर पर यूटीएफ -8 होता है। विंडोज वाईएमएमवी पर।

मानक सी ++ एन्कोडिंग के बारे में नहीं जानते हैं, आपको रूपांतरण करने के लिए ICU जैसी कुछ लाइब्रेरी का उपयोग करना चाहिए।

+1

इन 'कन्वर्ट' कार्यों का उपयोग करना मेरे लिए तार्किक लगता है; मैंने 'स्ट्रिंग :: wstring' और 'std :: string' के बीच स्विच करने के लिए फ़ंक्शंस का उपयोग करने का भी निर्णय लिया, जहां यह समझ में आता है, ऐप को पूरी तरह से' string_type' के साथ अपडेट करने के बजाय ... जो काफी समय लेता, स्ट्रिंग अक्षर को संबोधित करने के लिए अकेले रहने दें (और उन्हें 'एल' के साथ उपसर्ग) –

5

आप अपने आवेदन के भीतर एक स्ट्रिंग को कैसे स्टोर करते हैं, यह पूरी तरह से आपके ऊपर है - आखिरकार, जब तक तार आपके आवेदन के भीतर नहीं रहेंगे तब तक कोई भी नहीं जानता। समस्या तब शुरू होती है जब आप बाहरी दुनिया (कंसोल, फाइल, सॉकेट इत्यादि) से स्ट्रिंग पढ़ने या लिखने का प्रयास करते हैं और यह वह जगह है जहां ओएस मायने रखता है।

लिनक्स यूनिकोड के लिए बिल्कुल "अज्ञेयवादी" नहीं है - यह यूनिकोड को पहचानता है लेकिन मानक लाइब्रेरी फ़ंक्शन यूटीएफ -8 एन्कोडिंग मानते हैं, इसलिए यूनिकोड स्ट्रिंग मानक char सरणी में फिट होती है। दूसरी ओर, विंडोज़ यूटीएफ -16 एन्कोडिंग का उपयोग करता है, इसलिए आपको 16-बिट वर्णों का प्रतिनिधित्व करने के लिए wchar_t सरणी की आवश्यकता है।

typedef एस आपको प्रस्तावित ठीक काम करना चाहिए, लेकिन ध्यान रखें कि यह अकेले आपका कोड पोर्टेबल नहीं बनाता है। उदाहरण के तौर पर, यदि आप पोर्टेबल तरीके से फ़ाइलों में टेक्स्ट स्टोर करना चाहते हैं, तो आपको एक एन्कोडिंग चुननी चाहिए और सभी प्लेटफ़ॉर्म पर इसे चिपकाना चाहिए - इसके लिए कुछ प्लेटफ़ॉर्म पर एन्कोडिंग के बीच कनवर्ट करना आवश्यक हो सकता है।

3

लिनक्स यूनिकोड का समर्थन करता है, यह बस यूटीएफ -8 का उपयोग करता है। शायद आपके सिस्टम को पोर्टेबल बनाने का एक बेहतर तरीका International Components for Unicode का उपयोग करना होगा और यूटीएफ -8 अक्षरों वाले सभी std::string ऑब्जेक्ट्स का इलाज करना होगा, और उन्हें विंडोज फ़ंक्शंस का उपयोग करते समय आवश्यकतानुसार यूटीएफ -16 में परिवर्तित करना होगा। यूटीएफ -8 पर यूटीएफ -8 का उपयोग करना लगभग हमेशा समझ में आता है, क्योंकि यूटीएफ -8 कुछ सबसे अधिक इस्तेमाल किए जाने वाले वर्णों (जैसे अंग्रेजी *) के लिए कम जगह का उपयोग करता है और कम लगातार वर्णों के लिए अधिक जगह का उपयोग करता है, जबकि यूटीएफ -16 समान रूप से अंतरिक्ष को बर्बाद करता है सभी पात्रों के लिए, कोई फर्क नहीं पड़ता कि वे कितनी बार उपयोग किया जाता है।

जबकि आप अपने टाइपपीफ का उपयोग कर सकते हैं, इसका मतलब यह होगा कि आपको प्रत्येक एकल फ़ंक्शन की दो प्रतियां लिखनी होंगी जिन्हें तारों से निपटना होगा। मुझे लगता है कि यूटीएफ -8 में बस सभी आंतरिक कंप्यूटेशंस करने के लिए यह अधिक कुशल होगा और आवश्यकतानुसार इनपुट/आउटपुट करते समय आवश्यक होने पर यूटीएफ -16 से/उसमें अनुवाद करें।

* HTML, XML, और JSON कि एन्कोडिंग (उदाहरण के लिए "< एचटीएमएल >, < शरीर >, आदि) के हिस्से के रूप में अंग्रेजी का उपयोग मूल्यों की भाषा की परवाह किए बिना के लिए, यह अभी भी विदेशी के लिए एक जीत हो सकता है भाषाएं

1

लिनक्स के लिए समस्या और यूनिकोड का उपयोग करना यह है कि सभी आईओ और अधिकांश सिस्टम फ़ंक्शंस यूटीएफ -8 का उपयोग करते हैं और विस्तृत वर्ण प्रकार 32 बिट होता है। फिर जावा और अन्य प्रोग्राम्स में इंटरफेसिंग होता है जिसके लिए यूटीएफ -16 की आवश्यकता होती है।

यूनिकोड समर्थन के लिए एक सुझाव के रूप में, ओपनआरटीएल लाइब्रेरी को http://code.google.com/p/openrtl पर देखें जो सभी यूटीएफ -8, यूटीएफ -16 और यूटी का समर्थन करता है विंडोज़, लिनक्स, ओएसएक्स और आईओएस पर एफ -32। यूनिकोड समर्थन केवल चरित्र प्रकार नहीं है, बल्कि यूनिकोड संयोजन, सामान्यीकरण, केस फोल्डिंग, शीर्षक आवरण और लगभग 64 अलग-अलग यूनिकोड चरित्र गुण प्रति पूर्ण 32 हस्ताक्षर किए गए चरित्र हैं।

ओपनआरटीएल कोड अब नए सी ++ मानकों के लिए char8_t, char16_t और char32_t का समर्थन करने के लिए तैयार है, हालांकि मौजूदा सी और सी ++ कंपाइलर्स के लिए मैक्रोज़ का उपयोग करके समान वर्ण प्रकार समर्थित हैं। मुझे लगता है कि यूनिकोड और स्ट्रिंग्स प्रोसेसिंग के लिए यह हो सकता है कि यह आपकी लाइब्रेरी के लिए हो।

बिंदु यह है कि यदि आप OpenRTL का उपयोग करते हैं, तो आप OpenRTL "char_t" प्रकार का उपयोग कर सिस्टम बना सकते हैं। यह इस धारणा का समर्थन करता है कि आपकी संपूर्ण लाइब्रेरी को यूटीएफ 8, यूटीएफ 16 या यूटीएफ 32 मोड में भी लिनक्स पर बनाया जा सकता है, क्योंकि ओपनआरटीएल पहले से ही सभी इंटरफेसिंग को फाइल सिस्टम और आईओ सामान जैसे कई सिस्टम फंक्शंस में संभालने में कामयाब रहा है। उदाहरण के लिए इसका अपना प्रिंट_एफ फ़ंक्शन है।

डिफ़ॉल्ट रूप से char_t विस्तृत वर्ण प्रकार पर मैपिंग कर रहा है। तो विंडोज़ पर यह 32 बिट है और लिनक्स पर यह 32 बिट है। लेकिन आप उदाहरण के लिए इसे हर जगह 8 बिट भी बना सकते हैं। इसके अलावा मैक्रोज़ का उपयोग करके लूप के अंदर तेजी से यूटीएफ डिकोडिंग करने का समर्थन है।

तो wchar_t और char के बीच ifdeffing के बजाय, आप char_t और OpenRTL का उपयोग करके सब कुछ बना सकते हैं बाकी की देखभाल करते हैं।

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