2015-05-07 3 views
9

मैं यूनिकोड के बारे में कुछ लेख पढ़ने के लिए किया गया है और महसूस किया कि मैं अभी भी उलझन में वास्तव में क्या इसके बारे में क्या करने के लिए छोड़ दिया हूँ।C++ स्ट्रिंग शाब्दिक अभी भी भ्रमित

विंडोज प्लेटफॉर्म पर एक C++ प्रोग्रामर के रूप में, मुझे दिया विषयों ज्यादातर किसी भी शिक्षक से ही थे: हमेशा यूनिकोड वर्ण सेट का उपयोग करें; इसे टेम्पलेट करें या यदि संभव हो तो टीसीएचएआर का उपयोग करें; wchar_t, std :: wstring char, std :: string पर पसंद करते हैं।

#include <tchar.h> 
#include <string> 
typedef std::basic_string<TCHAR> tstring; 
// ... 
static const char* const s_hello = "핼로"; // bad 
static const wchar_t* const s_wchar_hello = L"핼로" // better 
static LPCTSTR s_tchar_hello = TEXT("핼로") // even better 
static const tstring s_tstring_hello(TEXT("핼로")); // best 

किसी तरह मैं में गड़बड़ है, और मैं अपने आप को नेतृत्व विश्वास है कि अगर मैं कहते हैं कि "कुछ", यह ASCII स्वरूपित है, और अगर मैं कहता हूँ एल "कुछ" यह यूनिकोड है इसका मतलब है कि। तब मैं इस पढ़ें:

प्रकार wchar_t अलग प्रकार जिनके मान समर्थित स्थानिक (22.3.1) के बीच निर्दिष्ट सबसे बड़ा विस्तारित वर्ण सेट के सभी सदस्यों के लिए विशिष्ट कोड का प्रतिनिधित्व कर सकते हैं। टाइप करें wchar_t के समान आकार, हस्ताक्षर, और संरेखण आवश्यकताओं (3.11) के रूप में अन्य अभिन्न प्रकारों में से एक के रूप में, इसके अंतर्निहित प्रकार कहा जाएगा। प्रकार char16_t और char32_t अंतर्निहित प्रकारों को क्रमशः, uint_least16_t और uint_least32_t के समान आकार, हस्ताक्षर और संरेखण के साथ अलग-अलग प्रकारों को दर्शाते हैं।

तो क्या हुआ? यदि मेरा लोकेल कोड 9 4 9 4 से शुरू होता है, तो wchar_t का विस्तार 9 4 9 + 2^(आकार (wchar_t) * 8) से है? और जिस तरह से यह बोलता है, 'मुझे लगता है कि सी ++ के कार्यान्वयन यूटीएफ एन्कोडिंग या क्या' का उपयोग नहीं करते हैं।

कम से कम, मैं समझता हूँ सकता है कि सब कुछ क्या स्थान में आवेदन पर है पर निर्भर करता है। इस प्रकार मैं परीक्षण किया:

#define TEST_OSTREAM_PRINT(x) \ 
std::cout << "----" << std::endl; \ 
std::cout << "cout : " << x << std::endl; \ 
std::wcout << "wcout : " << L##x << std::endl; 

int main() 
{ 
    std::ostream& os = std::cout; 

    std::cout << " * Info : " << std::endl 
       << "  sizeof(char) : " << sizeof(char) << std::endl 
       << "  sizeof(wchar_t) : " << sizeof(wchar_t) << std::endl 
       << "  littel endian? : " << IsLittelEndian() << std::endl; 
    std::cout << " - LC_ALL: " << setlocale(LC_ALL, NULL) << std::endl; 
    std::cout << " - LC_CTYPE: " << setlocale(LC_CTYPE, NULL) << std::endl; 

    TEST_OSTREAM_PRINT("핼로"); 
    TEST_OSTREAM_PRINT("おはよう。"); 
    TEST_OSTREAM_PRINT("你好"); 
    TEST_OSTREAM_PRINT("resume"); 
    TEST_OSTREAM_PRINT("résumé"); 

    return 0; 
} 

फिर उत्पादन किया गया था:

Info 
sizeof(char) = 1 
sizeof(wchar_t) = 2 
LC_ALL = C 
LC_CTYPE = C 
---- 
cout : 핼로 
wcout : ---- 
cout : おはよう。 
wcout : ---- 
cout : ?好 
wcout : ---- 
cout : resume 
wcout : resume 
---- 
cout : r?sum? 
wcout : r?um 

कोरियाई लोकेल के साथ एक और उत्पादन:

Info 
sizeof(char) = 1 
sizeof(wchar_t) = 2 
LC_ALL = Korean_Korea.949 
LC_CTYPE = Korean_Korea.949 
---- 
cout : 핼로 
wcout : 핼로 
---- 
cout : おはよう。 
wcout : おはよう。 
---- 
cout : ?好 
wcout : ---- 
cout : resume 
wcout : resume 
---- 
cout : r?sum? 
wcout : resume 

एक और उत्पादन:

Info 
sizeof(char) = 1 
sizeof(wchar_t) = 2 
LC_ALL = fr-FR 
LC_CTYPE = fr-FR 
---- 
cout : CU·I 
wcout : ---- 
cout : ªªªIªeª|¡£ 
wcout : ---- 
cout : ?u¿ 
wcout : ---- 
cout : resume 
wcout : resume 
---- 
cout : r?sum? 
wcout : resume 

यह पता चला तो मैं सही लोकेल, आवेदन न दें वर्णों की कुछ सीमा को संभालने में विफल रहता है, इससे कोई फर्क नहीं पड़ता कि मैंने char या wchar_t का उपयोग किया था। यह केवल समस्या नहीं है। विजुअल स्टूडियो चेतावनी देता है:

warning C4566: character represented by universal-character-name '\u4F60' cannot be represented in the current code page (949) 

मुझे यकीन नहीं है कि यह वर्णन कर रहा है कि मुझे आउटपुट या कुछ और के रूप में क्या मिल रहा है।

प्रश्न। सबसे अच्छा प्रथा क्या होगा और क्यों? कोई आवेदन मंच/कार्यान्वयन/राष्ट्र स्वतंत्र कैसे बना सकता है? स्रोत पर स्ट्रिंग अक्षर के साथ वास्तव में क्या होता है? आवेदन द्वारा स्ट्रिंग मानों का व्याख्या कैसे किया जाता है?

+1

अधिकतम संगतता के लिए: वर्णों को अपने स्रोत में बहुत ही बुनियादी ASCII वर्णों में रखें। स्ट्रिंग्स में \ x के साथ परिभाषित बाइट्स का उपयोग करके यूटीएफ 8 एन्कोडिंग का प्रयोग करें। C++ के नवीनतम संस्करण में नई u8 "\ u1234" सामग्री इसे आसान बनाती है, लेकिन यह अभी तक विजुअल स्टूडियो द्वारा समर्थित नहीं है। यह प्रश्न भी देखें: http://stackoverflow.com/questions/3768363/character-sets-not-clear – JCx

+1

'टीसीएचएआर एक बड़ी परेशानी है। जब तक आप विंडोज के वास्तव में पुराने संस्करणों का समर्थन नहीं कर रहे हैं, तो बस विंडोज़ चौड़े तार दें। अन्य चीजों के साथ संगतता के लिए, आप यूटीएफ -8 का उपयोग करके तारों को स्टोर कर सकते हैं और Windows API फ़ंक्शन का उपयोग करते समय उन्हें रूपांतरित कर सकते हैं। – chris

उत्तर

3

सी ++ में सामान्य यूनिकोड समर्थन नहीं है। आप तृतीय पक्ष पुस्तकालयों का उपयोग किये बिना सामान्य रूप से सी ++ में वैश्वीकृत एप्लिकेशन को विरेट नहीं कर सकते हैं। this अंतर्दृष्टि SO उत्तर पढ़ें। यदि आपको वास्तव में यूनिकोड का उपयोग करने वाले एप्लिकेशन को लिखने की आवश्यकता है तो मैं ICU लाइब्रेरी देखता हूं।

2

विंडोज, माइक्रोसॉफ्ट guarantees पर कि wchar_t यूनिकोड का समर्थन करता है, तो L"핼로" सही तरीका एक UTF-16 स्ट्रिंग एक const wchar_t* के रूप में शाब्दिक उत्पादन होता है।अन्य प्लेटफार्मों पर, यह जरूरी नहीं है, और आपको सी ++ 11 यूनिकोड स्ट्रिंग अक्षर (u8"...", u"...", और U"...") का उपयोग करना चाहिए यदि आपको पोर्टेबल होने के लिए अपने कोड की आवश्यकता है- उदाहरण के लिए, यूटीएफ -8 बनाने के लिए u8"핼로" का उपयोग करें एन्कोडेड const char* (विजुअल स्टूडियो 2015 के रूप में)।

दूसरी समस्या जो आप सामना कर रहे हैं वह है कि विजुअल स्टूडियो आपकी स्रोत फ़ाइल के एन्कोडिंग को कैसे समझता है। उदाहरण के लिए, ईयूसी-के.आर. (कोड पेज 949) है, जो कोड पेज में ªª 1252 (fr-एफआर) है क्योकि, आप अपने स्रोत ईयूसी-के.आर. में युक्त फ़ाइल को बचाया अगर लेकिन के लिए एन्कोडिंग है में 0xAA 0xAA के रूप में एन्कोड किया गया है इसे एक एफआर-एफआर लोकेल में संकलित करें, आपका शाब्दिक ªª एन्कोड करेगा।

यदि आपको अपने स्रोत में गैर-ASCII वर्ण शामिल करने की आवश्यकता है, तो आपको उन्हें answer to this question में वर्णित एक स्पष्ट बीओएम के साथ एक यूटीएफ (यानी, यूटीएफ -8/16/32) में सहेजना चाहिए।

+0

आप सही हैं। मैं यह निष्कर्ष निकालने वाला था कि माइक्रोसॉफ्ट व्यापक चरित्र स्ट्रिंग शाब्दिक (एल "समथिंग") को यूसीएस -2 में परिवर्तित करेगा, और बीएमपी के बाहर कुछ भी उन्हें पागल बना देगा। हालांकि, अतिरिक्त परीक्षण मुझे बता रहा है कि उन्हें वास्तव में यूटीएफ -16 के रूप में व्याख्या किया जाता है। धन्यवाद। – user2883715

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