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>));




newline