linux 打印中文宽字府,C++输出中文字符 C/C++多字节字符与宽字符的输出

原文:http://www.cnblogs.com/lixiaohui-ambition/archive/2012/07/17/2596490.html

C++输出中文字符

1. cout

场景1: 在源文件中定义 const char* str = "中文" 在 VC++ 编译器上,由于Windows环境用 GBK编码,所以字符串 "中文" 被保存为 GBK内码, 编译器也把 str 指向一个包含有 GBK编码的只读内存空间. 用 cout 输出 str 时, 由于中文Windows环境用GBK编码,所以把GBK编码的 str 内容输出到控制台,没问题.  场景2: 在Linux 下编辑一个文件 const char* str = "中文", 由于Linux普遍使用 UTF8 编码,所以在源文件里, "中文" 被保存为 UTF8内码. 然后在Windows中打开这个源文件,由于Windows使用GBK编码,所以VC++ 按照GBK去解释被保存为 UTF8 内码的 "中文", 显示为乱码.  2. wcout  在源文件中定义 const wchar_t* str = L"中文" 在 VC++ 编译器上,由于指定了L,所以字符串 "中文" 被保存为UNICODE内码(UCS2),编译器也把 str 指向一个包含有 UNICODE 编码的只读内存空间. 用 wcout 输出 str 时, wcout 首先调用 wcstomb_s() (即根据当前 local 转换, 如果没有设置local,则是经典的C local, 不认识中文)把 str 的内容转换后交给控制台,结果自然什么都不显示. (调试代码可以知道VC++ 2010 实现是一个字符一个字符输出,调用 wctomb_s)  原理 我们知道 cout 和 wcout 分别是 basic_ostream 的特化版本, 而 basic_ostream 调用 basic_streambuf 实际执行输出动作,针对 wchar_t,basic_streambuf有专门的特化函数,调用 fputwc 输出一个宽字符,而 fputwc 需要调用 wctomb_s 把宽字符转换后再输出. 我们知道wctomb_s 是依赖 locale 的,由于默认情况下是C locale,所以用中文内码调用 wctomb_s 会失败.  解决办法 设置当前系统的locale 替代默认的 "C" locale, 使 wctomb_s 等函数可以正常工作. 以下3种方法中的任意一种都可以达到目的.  1. C函数设置全局locale setlocale(LC_ALL, "");  2. C++ 设置全局locale std::locale::global(std::locale(""));  2. 单独为 wcout 设置一个 locale std::locale loc(""); std::wcout.imbue(loc);  结论 和Windows API 不同 C++中的各种 w版本的类或者函数并不能提高性能,因为它们都需要用 wc..to..mb 之类的函数转换为ANSI兼容编码然后调用标准库函数.或者,如果库函数的实现者愿意,针对Windows系统,宽字符的fputwc可以直接调用UNICODE版本的Windows API而不用转换.但是这些都跟C++语言本身没有什么关系.由于Windows内核是UNICODE的,所以直接用 UNICODE 字符串调用 Windows API会有一点点好处.  C++设计者的出发点: 我不管你用什么字符编码,与C++无关,要输出时:如果是单字节字符或者多字节字符,直接输出;如果是宽字符,则根据local转换为多字节字符,然后再输出. 即使将来UNICODE过时了(假设,假设而已),也不要紧,只要定义好新的local即可.对于C语言也是这样.

Windows设计者的出发点: 统一使用 Unicode 宽字符,解决一切问题

原文:http://blog.csdn.net/gonxi/article/details/5931006

C/C++多字节字符与宽字符的输出

使用C++标准库的iostream,可以方便地将控制台、文件、字符串以及其它可扩充的外部表示作为流来处理,但要处理中文,却会碰到很多问题。本人原来没怎么用过这个iostream,这几天尝试用这个写点东西,一会儿不能输出中文,一会儿不支持中文文件名的,搞得头大。网上搜了搜,没有发现适用于所有情况的解决方案。不过后来自己经过多次测试,基本解决了这些问题,现在写成文字作为一个总结,也供碰到同样问题的朋友参考。关于C语言中的 printf和wprintf的中文输出,本文也进行了探讨。    需要说明的是,我的开发环境是VS 2005(标准库当然也是微软实现的),不保证其它环境下是相同的效果。 1、cout和wcout   在缺省的C locale下,cout可以直接输出中文,但对于wcout却不行。对于wcout,需要将其locale设为本地语言才能输出中文:   wcout.imbue(locale(locale(),"",LC_CTYPE)); // ①   也有人用如下语句的,但这会改变wcout的所有locale设置,比如数字“1234”会输出为“1,234”。   wcout.imbue(locale(""));  2、ofstream和wofstream   在缺省的C locale下,ofstream能正确输出中文到文件中,但不支持中文文件名;wofstream支持中文文件名,但不能向文件中输出中文。要解决这个问题,需要在打开文件之前将全局locale设为本地语言。将全局locale设为本地语言后,ofstream和wofstream的问题都解决了,但 cout和wcout却不能输出中文了。要让cout和wcout输出中文,需要将全局locale恢复原来的设置,如下所示:   locale &loc=locale::global(locale(locale(),"",LC_CTYPE)); // ②   ofstream ofs("ofs测试.txt");   wofstream wofs(L"wofs测试.txt");   locale::global(loc); // ③   ofs<

你可能感兴趣的:(linux,打印中文宽字府)