2010-06-23 21 views
0

Récemment, je veux écrire un fichier texte en Unicode (UTF-16) sous Windows.Type d'encodage UTF-16, utilisant wofstream dans Windows

En faisant référence à http://www.codeproject.com/KB/stl/upgradingstlappstounicode.aspx, voici le code que j'applique.

Lorsque j'utilise Bloc-notes pour ouvrir le document, voici l'affichage. Newline semble disparaître !!!

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

Lorsque j'utilise Firefox avec le codage UTF-16 sélectionné, l'affichage est ici.

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

je tente d'ouvrir sous JEdit, en utilisant le codage suivant

  1. UTF-16 - Non. Affichage des ordures
  2. UTF-16BE - Non. Affichage des ordures
  3. UTF-16LE - Fin. Capable de montrer plusieurs lignes.

Je suppose que, je dois fournir des informations de commande d'octets supplémentaires? Mais comment?

Mon objectif est de faire en sorte que ce document UTF-16 puisse s'afficher correctement sous Bloc-notes, car mon client adore utiliser Notepad.

P/S S'IL VOUS PLAÎT! Ne me suggérez jamais d'utiliser UTF-8. Je vous remercie.

#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

Assurez-vous que vous écrivez une nomenclature (0xFEFF) au début. Avec des caractères de 16 bits, l'endianness devient un problème. Et assurez-vous que votre endl est en réalité un CR suivi d'un LF. Le Bloc-notes ne traite pas les LF solitaires comme des sauts de ligne. – cHao

+0

Notepad s'attend à ce que les fins de ligne Windows (CR + LF). Votre fichier a-t-il des fins de ligne CR + LF, ou est-ce simplement LF? (Essayez d'examiner votre fichier dans un éditeur hexadécimal.) – jamesdlin

Répondre

4

Lorsque vous faites ios::binary, le fichier est ouvert en mode binaire qui signifie passage à la ligne non convertis au bon \ r \ n encodage sous Windows.

Si vous écrivez "\r\n" au lieu de std :: endl, cela devrait fonctionner dans le Bloc-notes. Je ne suis pas sûr si c'est la meilleure solution.

+0

Ca marche super bien –