//原来一直用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; }