一个写Unicode 文本文件的方法

    技术2022-05-19  19

    //原来一直用C中wfopen,putwc这些东西写unicode的文件

    //一直没发现用wstring,wchar_t 的方法。 

    //最近在下面这个位置,发现一个好东西。 //http://www.codeproject.com/vcpp/stl/upgradingstlappstounicode.asp?df=100&forumid=16224&exp=0&select=788194 #include <locale> #include <stdlib.h> #include <TCHAR.h> #include <windows.h> #include <iostream> #include <fstream> #include <string> using namespace std;

    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 size_t 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 ) / { /     NullCodecvt* pNullCodecvt = new NullCodecvt ; /     locale loc = locale::classic() ; /     loc._Addfac( pNullCodecvt , NullCodecvt::id, NullCodecvt::_Getcat() ) ; /     (outputFile).imbue( loc ) ; / }

    ///自己随便以下写个测试,提醒一下自己别忘了

    int main() {     string str1="abc中文Chinese与英文English混排ss,,mbstowcs转换";   string str="efg中文Chinese与英文English混排ss/",,MultiByteToWideChar转换";   wstring str2=L"真是折腾人阿!!!";   wchar_t wst[100]={};   char czz[101]="Begin被替换End";   WCHAR tx1[100]={};          //  TCHAR

      cout<<str<<endl;         cout<<czz<<endl;   locale loc(""),oldloc;            setlocale(LC_ALL,"");     //设置本地默认   // setlocale(LC_ALL,"CHS");    //直接指定本地           mbstowcs(wst, str1.c_str(), str1.size()+1);        setlocale(LC_ALL,"C");     //恢复默认      cout<<czz<<endl;          //不恢复的话,这里输出貌似就出问题了。

      setlocale(LC_ALL,"");     //设置本地默认   lstrcpy(wst,str2.c_str());    wcstombs(czz,str2.c_str(),sizeof(czz));   setlocale(LC_ALL,"C");     //用完恢复 

      strcpy(czz,"Begin被替换End");

      MultiByteToWideChar( CP_ACP,0, str.c_str(),strlen(str.c_str())+1, tx1,sizeof(tx1)/sizeof(tx1[0]));          WideCharToMultiByte(CP_ACP,0,tx1,lstrlen(tx1)+1,czz,sizeof(czz)/sizeof(czz[0]),NULL,NULL);    oldloc=wcout.imbue(loc);           //设置,,如果不进行设置,输出将不正确          wcout<<endl;    wcout<<tx1<<endl;    wcout<<wst<<endl;        cout<<czz<<endl;          wcout<<str2<<endl;    wcout<<"the end"<<endl;

        wcout.imbue(oldloc);             //恢复   

      //建一个Unicode的文本文件存储之。   wofstream UniFile;   UniFile.open("C://uinFile.txt",ios::out|ios::binary);    //       UniFile<<UniFile.narrow(0xFF);               //设置Unicode文本文件标志.这两个是窄字符   UniFile<<UniFile.narrow(0xFE);

      IMBUE_NULL_CODECVT( UniFile ) ;               //为什么要用这个,原来写入文件时字符被默认的本地化对象转换为nawwow了。所以总是不成功。   //现在通过这一步,让流使用自定义的本地对象进行对应的转换。         UniFile<<wst<<UniFile.widen('/r')<<UniFile.widen('/n');      //使用回车换行都要宽字符化。         UniFile<<tx1<<UniFile.widen('/r')<<UniFile.widen('/n');         UniFile<<str2<<UniFile.widen('/r')<<UniFile.widen('/n');                  //UniFile.imbue(loc);      UniFile.close();

     system("pause");  return 0; }


    最新回复(0)