2017-09-19 5 views
9

여기 내 모든 노력에도 불구하고 해결할 수없는 문제가 있습니다. 그래서 나는 완전히 붙어있어, 제발 도와주세요! 일반, "ASCII"모드의UTF-16 스트림의 CRLF가 잘못 되었습니까?

다음과 같은 단순화 된 파일 및 스트림 출력

FILE *fa = fopen("utfOutFA.txt", "w"); 
fprintf(fa, "Line1\nLine2"); 
fclose(fa); 
ofstream sa("utfOutSA.txt"); 
sa << "Line1\nLine2"; 
sa.close(); 

결과, 자연적으로 정확히 같은 텍스트 파일 (16 진수 덤프) :

00000000h: 4C 69 6E 65 31 0D 0A 4C 69 6E 65 32    ; Line1..Line2 

새를 \n 줄은 CRLF : 0D 0A (Windows의 경우 일반)으로 확장됩니다.

이제 우리는 유니 코드 출력, 즉 일종의 "기본"인 UTF-16 LE에 대해 동일한 작업을 수행합니다. 이 내용에

FILE *fu = fopen("utfOutFU.txt", "w, ccs=UNICODE"); 
fwprintf(fu, L"Line1\nLine2"); 
fclose(fu); 

결과 파일 출력 : 0D 00 0A 00 : CRLF를 포함하여 BOM 및 엔디안을 고려 완벽하게 올바른 보이는

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. 

. 그러나, 유사한 스트림 출력

한 바이트에서
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. 

이유는 CRLF의 잘못된 확장은 다음과 같습니다 0D 0A 00. 이거 버그 야? 아니면 내가 잘못한 짓을 한거야?

Microsoft Visual Studio 컴파일러 (14.0 및 기타)를 사용합니다. 나는 \n 대신에 endl 스트림을 사용해 보았습니다 - 동일한 결과! 먼저 su.imbue()을 입력하고 su.open()을 입력하려고했습니다. 0D 0A

내가 문제에 대한 아이디어와 의견을 주셔서 감사합니다 : CRLF 등의 문제가 ASCII 모드에서와 동일하게 유지하지 - 나는 또한 UTF-8 출력 (스트림 파일에 대한 ccs=UTF-8codecvt_utf8)를 확인.

+0

이것은 UTF-16이 홀수 바이트를 가질 수 없기 때문에 버그 일 가능성이 큽니다. – CAF

답변

2

에 새 로캘을 imbue()으로 지정하면 원래 로캘이 지워집니다. locale::empty()을 사용하지 말고 대신 su.getloc()을 사용하십시오. 따라서 새 로켈은 수정하기 전에 이전 로켈을 복사합니다.

또한 쪽지에서 codecvt_utf16의 마지막 템플릿 매개 변수는 비트 마스크이므로 codecvt_mode(generate_header + 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>)); 
+1

각 피연산자의 비트가 겹치지 않지만 포인트가 좋은 경우에는'+'와'|'사이에 차이가 없습니다. –

+0

제게'getloc()'을 보여 주셔서 고마워요. 저는이 분야에서 꽤 초보자입니다. – lariona

+0

codecvt 모드는 초기 단계에서'|'를 사용했습니다. 컴파일러'error C2440 : 'specialization'으로 고민하다가 '+'로 변경했습니다 : 'int'에서 'std :: codecvt_mode'로 변환 할 수 없습니다; 마지막으로 expliticit 캐스트를 추가해야했지만 다시'|'로 변경하는 것을 무시했습니다. 어쨌든 고마워. – lariona