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
Post a Comment