c++ - यूटीएफ-16 धारा में गलत सीआरएलएफ?
visual-c++ unicode (1)
यहाँ एक समस्या है जो मैं अपने सभी प्रयासों के बावजूद हल नहीं कर सकता तो मैं पूरी तरह से फंस गया हूँ, कृपया मदद करो!
नियमित रूप से, "एएससीआईआई" मोड में निम्न सरलीकृत फाइल और स्ट्रीम आउटपुट हैं
FILE *fa = fopen("utfOutFA.txt", "w");
fprintf(fa, "Line1\nLine2");
fclose(fa);
ofstream sa("utfOutSA.txt");
sa << "Line1\nLine2";
sa.close();
परिणाम, स्वाभाविक रूप से, ठीक उसी टेक्स्ट फाइल में (हेक्स डंप):
00000000h: 4C 69 6E 65 31 0D 0A 4C 69 6E 65 32 ; Line1..Line2
जहां नई पंक्ति \n
को सीआरएलएफ में विस्तारित किया गया है: 0D 0A
- विंडोज के लिए सामान्य
अब, हम यूनिकोड आउटपुट के लिए भी ऐसा ही करते हैं, अर्थात् यूटीएफ -16 ले जो "डिफ़ॉल्ट" का एक प्रकार है। फ़ाइल आउटपुट
FILE *fu = fopen("utfOutFU.txt", "w, ccs=UNICODE");
fwprintf(fu, L"Line1\nLine2");
fclose(fu);
इस सामग्री में परिणाम:
00000000h: FF FE 4C 00 69 00 6E 00 65 00 31 00 0D 00 0A 00 ; ÿþL.i.n.e.1.....
00000010h: 4C 00 69 00 6E 00 65 00 32 00 ; L.i.n.e.2.
जो सीओएलएफ: 0D 00 0A 00
सहित बीओएम और एंडियननेस पर विचार करने में बिल्कुल सही लग रहा है हालांकि, समान प्रवाह आउटपुट
wofstream su("utfOutSU.txt");
su.imbue(locale(locale::empty(), new codecvt_utf16<wchar_t, 0x10ffffUL,
codecvt_mode(generate_header + little_endian)>));
su << L"Line1\nLine2";
su.close();
एक बाइट कम और संपूर्ण ग़लत टेक्स्ट फ़ाइल में परिणाम:
00000000h: FF FE 4C 00 69 00 6E 00 65 00 31 00 0D 0A 00 4C ; ÿþL.i.n.e.1....L
00000010h: 00 69 00 6E 00 65 00 32 00 ; .i.n.e.2.
कारण सीआरएलएफ का गलत विस्तार है: 0D 0A 00
क्या यह एक बग है? या मैंने कुछ गलत किया है?
मैं माइक्रोसॉफ्ट विज़ुअल स्टूडियो कंपाइलर (14.0 और अन्य) का उपयोग करता हूं। मैंने \n
की बजाय स्ट्रीम endl
का उपयोग करने की कोशिश की - वही परिणाम! मैंने पहले su.imbue()
डाल दिया और फिर su.open()
- सब एक ही! मैंने यूटीएफ -8 आउटपुट (फाइल के लिए ccs=UTF-8
और धारा के लिए codecvt_utf8
) की भी जांच की - कोई समस्या नहीं है क्योंकि codecvt_utf8
एएससीआईआई मोड के समान रहता है: 0D 0A
मैं इस मुद्दे पर किसी भी विचार और टिप्पणियों की सराहना करता हूं।
जब आप std::wofstream
imbue()
std::wofstream
में एक नया स्थान बना रहे हैं, तो आप अपने मूल स्थान को मिटा रहे हैं locale::empty()
उपयोग न करें, इसके बजाय su.getloc()
उपयोग करें, ताकि नया लोकेल उसे संशोधित करने से पहले पुराने स्थान की प्रतिलिपि बना सके।
साथ ही, एक तरफ नोट पर, codecvt_utf16
का अंतिम टेम्प्लेट पैरामीटर codecvt_utf16
है, इसलिए codecvt_mode(generate_header + little_endian)
वास्तव में std::generate_header | std::little_endian
होना चाहिए std::generate_header | std::little_endian
इसके बजाय std::generate_header | std::little_endian
su.imbue(std::locale(su.getloc(), new codecvt_utf16<wchar_t, 0x10ffffUL,
std::generate_header | std::little_endian>));