2010-06-23 4 views
0

최근에 Windows에서 유니 코드 (UTF-16)로 텍스트 파일을 작성하려고합니다.Windows에서 wofstream을 사용하는 UTF-16 인코딩 유형

http://www.codeproject.com/KB/stl/upgradingstlappstounicode.aspx을 참조하여 다음 코드를 적용합니다.

메모장을 사용하여 문서를 열면 여기에 디스플레이가 있습니다. 줄 바꿈이 사라지는 것 같습니다! I 선택 UTF-16 인코딩을 사용할 때 파이어 폭스

alt text http://sites.google.com/site/yanchengcheok/Home/notepad.png

, 여기에 표시된다. 아니 -

alt text http://sites.google.com/site/yanchengcheok/Home/firefox-utf16-encoding.PNG

나는 다음과 같은 인코딩

  1. UTF-16을 사용하여, JEDIT에서 열어보십시오. 쓰레기 표시.
  2. UTF-16BE - 아니요. 쓰레기 표시.
  3. UTF-16LE - 좋습니다. 여러 줄을 표시 할 수 있습니다.

내 생각에 추가 바이트 주문 정보를 제공해야합니까? 그러나 어떻게?

내 고객은 메모장을 사용하는 것을 좋아하기 때문에이 UTF-16 문서를 메모장 아래에 잘 표시 할 수 있습니다.

P/S 제발! UTF-8을 사용하여 저를 제안하지 마십시오. 고맙습니다. 당신이 ios::binary을 수행 할 때

#include <iostream> 
#include <fstream> 
#include <iomanip> 
#include <locale> 
#include <windows.h> 
#include <tchar.h> 
// For StringCchLengthW. 
#include <Strsafe.h> 
#include <cassert> 

using namespace std; 

// appearing in the NullCodecvtBase typedef. 
using std::codecvt ; 
typedef codecvt < wchar_t , char , mbstate_t > NullCodecvtBase ; 

class NullCodecvt 
    : public NullCodecvtBase 
{ 

public: 
    typedef wchar_t _E ; 
    typedef char _To ; 
    typedef mbstate_t _St ; 

    explicit NullCodecvt(size_t _R=0) : NullCodecvtBase(_R) { } 

protected: 
    virtual result do_in(_St& _State , 
        const _To* _F1 , const _To* _L1 , const _To*& _Mid1 , 
        _E* F2 , _E* _L2 , _E*& _Mid2 
        ) const 
    { 
     return noconv ; 
    } 
    virtual result do_out(_St& _State , 
        const _E* _F1 , const _E* _L1 , const _E*& _Mid1 , 
        _To* F2, _E* _L2 , _To*& _Mid2 
        ) const 
    { 
     return noconv ; 
    } 
    virtual result do_unshift(_St& _State , 
      _To* _F2 , _To* _L2 , _To*& _Mid2) const 
    { 
     return noconv ; 
    } 
    virtual int do_length(_St& _State , const _To* _F1 , 
      const _To* _L1 , size_t _N2) const _THROW0() 
    { 
     return (_N2 < (size_t)(_L1 - _F1)) ? _N2 : _L1 - _F1 ; 
    } 
    virtual bool do_always_noconv() const _THROW0() 
    { 
     return true ; 
    } 
    virtual int do_max_length() const _THROW0() 
    { 
     return 2 ; 
    } 
    virtual int do_encoding() const _THROW0() 
    { 
     return 2 ; 
    } 
} ; 

#define IMBUE_NULL_CODECVT(outputFile) \ 
{ \ 
(outputFile).imbue(std::locale(locale::classic(), new NullCodecvt)) ; \ 
} 

int main() 
{ 
    std::wofstream file; 
    IMBUE_NULL_CODECVT(file) ; 
    file.open(L"C:\\可以爱我吗.TXT", ios::out | ios::binary); 
    file << L"ABC" << std::endl; 
    file << L"我爱你" << std::endl; 
    file << L"Bye bye" << std::endl; 

    printf("done\n"); 
    getchar(); 
} 
+0

시작 부분에 BOM (0xFEFF)을 쓰는지 확인하십시오. 16 비트 문자를 사용하면 엔디안 니스가 문제가됩니다. 그리고 endl이 실제로 CR 뒤에 LF가 오는 지 확인하십시오. 메모장은 줄 바꿈으로 단독 LF를 처리하지 않습니다. – cHao

+0

메모장에 Windows 줄 끝 문자 (CR + LF)가 있어야합니다. 파일에 CR + LF 행 끝이 있거나 LF입니까? (16 진수 편집기에서 파일을 검사 해보십시오.) – jamesdlin

답변

4

이 파일은 Windows의 올바른의 \ r \ n 인코딩으로 변환되지 않습니다 줄 바꿈을 의미 바이너리 모드로 열립니다.

std :: endl 대신 "\r\n"을 쓰면 메모장에서 작동합니다. 이것이 최선의 해결책인지 확실하지 않습니다.

+0

그냥 훌륭하게 작동합니다. –

관련 문제