wprintf、wcout输出中文和unicode中文字符串的转换问题

本来想搞明白点wchar_t,就写了个很简单的wcout的例子,结果中文无法输出,然后换成wprintf,却还是不行~于是在网上搜啊搜,总算解决了问题,总结一下:

试着运行下面的代码:

wchar_t *ws = L"你好";
wcout << ws << endl;

这样没有任何输出,必须将locale设为本地语言,就是在wcout前加入下面这句话就可以:

std::wcout.imbue( locale(locale(), "", LC_CTYPE) );
//注:如果无效,可以试试把 LC_CTYPE 改成 LC_ALL

也可以指定中文语言:

std::wcout.imbue( locale(locale(), "chs", LC_CTYPE) );  

很多资料用这句话wcout.imbue(locale("")),这样会改变wcout的所有locale设置,比如int型的1234会显示成1.234

可是wprintf还是不可用,必须在使用前把C语言的locale设置成本地语言:

setlocale( LC_CTYPE, "" );//或者"chs"

但这个设置是全局的,后果就是会让cout和wcout无法再输出中文,所以我们在用完后必须设置回原来的:

setlocale( LC_CTYPE, "" );  
wprintf( L"%s", L"你好" );
setlocale( LC_CTYPE, "C" );

一般情况下"C"就是原来的,但也可能不是,这时候我们可以将老的locale保存,用完后还原:

char* old_locale = _strdup( setlocale(LC_CTYPE,NULL) ); 
setlocale( LC_CTYPE, "" );
wprintf( L"%s", L"你好" );
setlocale( LC_CTYPE,  old_locale );

wofstream本没有想用,不过既然查到了就一并记下来:

在缺省的locale下,ofstream能正确输出中文到文件中,但不支持中文文件名,wofstream支持中文文件名,但不能向文件中输出中文。要解决这个问题,需要在打开文件之前将全局locale设为本地语言。将全局locale设为本地语言后,ofstream和wofstream的问题都解决了,但 cout和wcout却不能输出中文了,所以还是要将全局locale恢复原来的设置:

locale &loc=locale::global(locale(locale(),"",LC_CTYPE));
ofstream ofs("你好.txt");
wofstream wofs(L"你好.txt");
locale::global(loc);
ofs<<"test测试"<<1234<<endl;
wofs<<L"Another test还是测试"<<1234<<endl;

wchar_t*与char*的转换函数wcstombs和mbstowcs也需要类似设置才有效,下面是一个例子:

wchar_t *ws = L"你好吗";
char cs[10];
wchar_t ws2[10];
unsigned int len = 2 * ( wcslen(ws) + 1 );

char* old_locale = _strdup( setlocale(LC_CTYPE,NULL) );  
setlocale( LC_CTYPE, "" );
wcstombs( cs, ws,len );
mbstowcs( ws2, cs, len );
setlocale( LC_CTYPE, old_locale );

cout << cs << endl;

std::wcout.imbue( locale(locale(), "", LC_CTYPE) );
wcout << ws2 << endl;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值