Unicode literals in Visual C++ -


निम्न कोड पर विचार करें:

  #include & lt; स्ट्रिंग & gt; # शामिल करें & lt; fstream & gt; # शामिल करें & lt; iomanip & gt; Int main () {std :: string s = "\ xe2 \ x82 \ xac \ u20ac"; Std :: ऑफस्ट्रीम आउट ("test.txt"); बाहर & lt; & lt; S.length () & lt; & lt; ":" & Lt; & lt; S & lt; & lt; std :: endl; बाहर & lt; & lt; std :: endl; out.close (); }  

लिनक्स पर जीसीसी 4.8 के तहत (उबंटु 14.04), फ़ाइल test.txt इसमें शामिल है:

  6: € €  

विंडोज के अंतर्गत दृश्य सी ++ 2013 में, इसमें यह शामिल है:

  4: € \ x80  

( '\ X80' का मतलब है कि एक 8-बिट वर्ण 0x80)।

मैं या तो कंपाइलर को को std का उपयोग करके आउटपुट करने में असमर्थ हूँ :: wstring

दो प्रश्न:

  • माइक्रोसॉफ्ट कंपाइलर को लगता है कि यह char * के साथ क्या कर रहा है? स्पष्ट रूप से यह सांकेतिक शब्दों में बदलना करने के लिए कुछ कर रहा है, लेकिन जो स्पष्ट नहीं है।
  • std :: wstring और std :: का उपयोग करके उपरोक्त कोड को फिर से लिखने का सही तरीका क्या है Wofstream ताकि वह दो वर्णों को आउटपुट कर सके?

इसका कारण यह है कि आप \ u20ac का प्रयोग कर रहे हैं जो कि एक एएससीआईआई स्ट्रिंग में यूनिकोड अक्षर है।

एमएसवीसी एनकोड "\ xe2 \ x82 \ xac \ u20ac " जैसा 0xe2, 0x82, 0xac, 0x80, जैसा कि 4 संकीर्ण वर्ण हैं I यह अनिवार्य रूप से \ u20ac को 0x80 के रूप में एन्कोड करता है क्योंकि यह मानक के लिए यूरो वर्ण को मैप किया गया है

जीसीसी यूनिकोड की शाब्दिक / u20ac को 3-बाइट में कनवर्ट कर रहा है UTF-8 अनुक्रम 0xe2, 0x82, 0xac इसलिए परिणामी स्ट्रिंग को 0xe2, 0x82, 0xac, 0xe2, 0x82, 0xac के रूप में समाप्त होता है।

यदि आप std :: wstring = L "\ xe2 \ x82 \ xac \ u20ac" का उपयोग करते हैं, इसे एमएसवीसी द्वारा 0xe2, 0x00, 0x82, 0x00, 0xac, 0x00, 0xac, 0x20 < / कोड> 4 चौड़े वर्ण हैं, लेकिन जब आप एक यूटीएफ -8 को यूटीएफ -16 के साथ हाथ से बनाते हैं, तो परिणामस्वरूप स्ट्रिंग ज्यादा मायने नहीं रखती। यदि आप std :: wstring = L "\ u20ac \ u20ac" का उपयोग करते हैं, तो आप अपेक्षा करते हुए विस्तृत-स्ट्रिंग में 2 यूनिकोड वर्ण प्राप्त करते हैं।

अगली समस्या है कि एमएसवीसी की ऑफस्ट्रीम और वोफस्ट्रीम हमेशा एएनएसआई / एएससीआईआई में लिखते हैं। इसे यूटीएफ -8 में लिखने के लिए आपको & lt; codecvt & gt; (वीएस 2010 या बाद के संस्करण) का उपयोग करना चाहिए:

  #include & lt; स्ट्रिंग & gt; # शामिल करें & lt; fstream & gt; # शामिल करें & lt; iomanip & gt; # शामिल करें & lt; codecvt & gt; Int main () {std :: wstring s = L "\ u20ac \ u20ac"; Std :: wofstream आउट ("test.txt"); Std :: लोकेल लोकल (std :: locale :: क्लासिक (), नया std :: codecvt_utf8 & lt; wchar_t & gt;); out.imbue (loc); बाहर & lt; & lt; S.length () & lt; & lt; एल ":" & lt; & lt; S & lt; & lt; std :: endl; बाहर & lt; & lt; std :: endl; out.close (); }  

और UTF-16 (या अधिक विशेष रूप से यूटीएफ -16LE) लिखना:

  #include & lt; स्ट्रिंग & gt; # शामिल करें & lt; fstream & gt; # शामिल करें & lt; iomanip & gt; # शामिल करें & lt; codecvt & gt; Int main () {std :: wstring s = L "\ u20ac \ u20ac"; Std :: wofstream आउट ("test.txt", std :: ios :: द्विआधारी); Std :: locale loc (std :: locale :: क्लासिक (), नया std :: codecvt_utf16 & lt; wchar_t, 0x10ffff, std :: little_endian & gt;); out.imbue (loc); बाहर & lt; & lt; S.length () & lt; & lt; एल ":" & lt; & lt; S & lt; & lt; एल "\ r \ n"; बाहर & lt; & lt; एल "\ r \ n"; out.close (); }  

नोट: UTF-16 के साथ आपको भ्रष्टाचार से बचने के लिए टेक्स्ट मोड की बजाय एक बाइनरी मोड का उपयोग करना है, इसलिए हम std :: endl और सही एंड-लाइन-टेक्स्ट फ़ाइल व्यवहार प्राप्त करने के लिए L "\ r \ n" का उपयोग करना होगा।


Comments

Popular posts from this blog

sqlite3 - UPDATE a table from the SELECT of another one -

c# - Showing a SelectedItem's Property -

javascript - Render HTML after each iteration in loop -