wofstream,wcout无法输出unicode的真相

21 篇文章 0 订阅

之前我转载过一篇ofstream和wofstream与中文输出问题,让我初步知道如何解决这类问题。第一次我没有在意,按照文章中做的方法去做,然后程序就运行正常了。我试图去记住这些规则,但是我后来发现,太难了。以至于我在最近一次使用到 std::wofstream 类的时候,发现我无法往其中输入unicode字符。让我找了几个小时的bug,于是我今天就花了两个小时,在网上搜索资料,以及自己写一些测试工程,调试跟踪 std::wofstream 的相关函数,差不多明白了原因。下面让我用最简单的方式,让你真正理解,wofstream,wcout无法输出unicode字符的原因。

  1. 首先visual studio(也可以说微软)版本的 wofstream,wcout最终输出的字符编码都是ANSI(多字节编码,MultiByte)例如:
        std::wofstream fOut;
        fOut.open( L"你好1.txt", std::ios::trunc );
        fOut << L"徐杰" << std::endl;
        fOut.close();

    这样简短的代码,最后输出的文件编码方式是:ANSI。这也是最令我吃惊的。因为我以为 wofstream 比 ofstream 多一个 w,意思是可以直接写入unicode字符(宽字符,wide-char)。但实际上,多一个 w 只是表明其支持 unicode 文件名(或者说全路径文件名)。

  2. wofstream,wcout 在处理 unicode字符 时,必须进行内部编码转换(unicode -> ansi )。
    看完第一点之后,第二点是很自然的,因为 wofstream,wcout 最后都是要输出 ansi 的,所以必须进行字符编码转换。

  3. wofstream,wcout(或者说C++)进行编码转换的时候,需要知道将 unicode 转换到哪个国家的 ansi 编码(code page )。
    code page 的信息存放在 locale 的 codecvt 里面。 C++ 默认的 locale 中的 codecvt 没有保存任何国家的 code page。所以此时调用
        wofstream << L"徐杰"; 

  4. std::locale( std::locale(),"",std::locale::ctype )会创建当前系统环境下locale,这个locale中会保存这个系统 ansi 使用 code page。
        std::locale oNewLocale( std::locale(),"",std::locale::ctype );
        std::locale oPreviousLocale = std::locale::global( oNewLocale );
        //...文件打开,保存信息,关闭文件等操作。
        std::locale::global( oPreviousLocale );
    所以我们使用时,先将本地locale设置上去,然后用完之后,在设置回来(以免影响到其他系统的使用)。locale 类的相关用法请参考相关的C++标准。也可参考此链接:locale使用说明
知道原因之后,你可以更自如的选择使用 wofstream, ofstream, wcout, cout了。

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值