`
836811384
  • 浏览: 548876 次
文章分类
社区版块
存档分类
最新评论

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 首先调用 wcstombs() (即根据当前 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 宽字符,解决一切问题

分享到:
评论

相关推荐

    C++ 汉字UTF-8字符串处理类库

    很多人喜欢用CString 或std:string,但是他们的缺点是不能完成汉字各种类型之间的转换,提供三种类库ascString,ucsString,utfString以及工具utfCount,utf8_ucs2_t,tcf8_ucs4_t类库,用于各种字符串之间的直接转换`...

    汉字字符串输出首字母源代码

    汉字字符串输出首字母源代码 可以把代码直接放到自己的程序中.通过函数调用.简单易懂~

    opencv输出中文字符,并控制字符大小.rar

    OpenCV输出中文字符,在CvxText类的基础上做了修改,能够控制输出字符的大小。压缩包中包含修改前后的源代码、测试代码、freetype库(ft28)、字体文件(.tff)、说明文档、.lib文件。配合博客中的说明更易理解。...

    递归反转字符串(带中文)

    该文档是反转字符串的,很多资源只是反转英文字符串,该文档包括可以反转中文的,并且有递归和非递归的方法。仅仅只是一个cpp文件,只要新建一个新的空工程,直接加载该cpp就可以运行使用了。

    Linux Opencv在图像上写中文字符

    Linux环境,利用Opencv freetype在图像上写中文字符,含字体文件、源码、CMakeLists配置

    C++处理两个整数表示的字符(英文/中文/符号混合)

    ECletter是一个英文/中文/符号字符(占两个int),支持取单独的一位int、输入输出、比较,支持用一个int、两个int、const char[]、wchar_t初始化和赋值;ECletters是一个固定大小的ECletter数组,但有其它的功能:用...

    将CString字符串(包含中文,字母,数字等)保存到指定路径txt文件

    将CString字符串(包含中文,字母,数字等)保存到指定路径txt文件

    点阵输出汉字,用汉字字库输出放大的汉字

    点阵输出汉字,用汉字字库输出放大的汉字,汉字字库,c++

    C++编程思想(第2版 第2卷)

    介绍C++的字符串、输入输出流、STL算法、容器和模板的现代用法,包括模板元编程;解释多重继承问题的难点,展示RTTI的实际使用,描述了典型的设计模式及其实现,特别介绍被认为是标准C++下一版特征之一的多线程处理...

    C++下的OpenGL文字显示的完美解决方案

    NULL 博文链接:https://kungsoft.iteye.com/blog/318875

    C++编程思想(Thinking in C++)完美版pdf

    第4章 输入输出流 第5章 深入理解模板 第6章 通用算法 第7章 通用容器 第三部分 专题 第8章 运行时类型识别 第9章 多重继承 第10章 设计模式 第11章 并发 附录 附录A 推荐读物 附录B 其他 索引 

    C++统计中英文大小写字母、数字、空格及其他字符个数的方法

    本文实例讲述了C++统计中英文大小写字母、数字、空格及其他字符个数的方法。分享给大家供大家参考,具体如下: /* * 作 者: 刘同宾 * 完成日期:2012 年 11 月 28 日 * 版 本 号:v1.0 * 输入描述: * 问题描述: ...

    C++编程思想

    介绍c++的字符串、输入输出流的现代用法;解释多重继承问题的难点,描述了典型的设计模式及其实现,特别介绍了多线程处理编程技术。《C++编程思想(两卷合订本)》是c++领域内一本权威的著作,书中的内容、讲授方法、...

    C++编程思想(中文版pdf高清)(1,2卷)

    介绍C++的字符串、输入输出流、STL算法、容器和模板的现代用法,包括模板元编程;解释多重继承问题的难点,展示RTTI的实际使用,描述了典型的设计模式及其实现,特别介绍被认为是标准C++下一版特征之一的多线程处理...

    Absolute C++中文版(原书第2版)-完美的C++教程,文档中还包含英文版

    9.1.3 C字符串的输入和输出 250 9.2 字符操作工具 252 9.2.1 字符输入/输出 252 9.2.2 成员函数get和put 252 9.2.3 成员函数putback、peek和ignore 257 9.2.4 字符操作函数 258 9.3 标准string类 261 9.3.1 ...

    Thinking in C++ 中文版

    介绍C++的字符串、输入输出流、STL算法、容器和模板的现代用法,包括模板元编程;解释多重继承问题的难点,展示RTTI的实际使用,描述了典型的设计模式及其实现,特别介绍被认为是标准C++下一版特征之一的多线程处理...

    VC++汉字转国标码(一个汉字变成2个16进制码)

    输入一串汉字和数字的混合字符, 经过程序转换, 对应输出一串16进制码(数字-〉ASII码,汉字—〉国标码)

    汉字GBK首字母(含生僻字)C++实现代码文件

    汉字GBK首字母(含生僻字)C++实现代码文件 支持传入字符串输出首字母。 支持特例汉字、多音字、全角英文数字的转换。

    C++ Primer第四版【中文高清扫描版】.pdf

    1.2.1 标准输入与输出对象 5 1.2.2 一个使用IO库的程序 5 1.3 关于注释 8 1.4 控制结构 10 1.4.1 while语句 10 1.4.2 for语句 12 1.4.3 if语句 14 1.4.4 读入未知数目的输入 15 1.5 类的简介 17 1.5.1 Sales_item类...

    C++编程思想_中文清晰PDF

    介绍C++的字符串、输入输出流、STL算法、容器和模板的现代用法,包括模板元编程;解释多重继承问题的难点,展示RTTI的实际使用,描述了典型的设计模式及其实现,特别介绍被认为是标准C++下一版特征之一的多线程处理...

Global site tag (gtag.js) - Google Analytics