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++输出中文字符的更多相关文章
- Dev Cpp 输出中文字符问题
最近 c++ 上机作业,vc++6.0 挂了没法用,只好用 Dev Cpp 先顶替一下,然而在遇到输出中文字符的时候出现了乱码的情况,但这种情况又非常诡异.于是简单了解了一下写成此博客. [写在前面] ...
- C++输出中文字符(转)
C++输出中文字符 1. cout 场景1: 在源文件中定义 const char* str = "中文" 在 VC++ 编译器上,由于Windows环境用 GBK编码,所以字符串 ...
- php输出中文字符
中文字符不可以使用imagettftext()函数在图片中直接输出,如果要输出中文字符,需要先使用iconv()函数对中文字符进行编码,语法格式如下:string iconv ( string $in ...
- Java文件处理之FileReader可输出中文字符
import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; public ...
- 解决IAR printf函数输出中文字符乱码问题
首先看一下IAR的中文字符的坑 这会对调试造成很大的干扰,因为眼见不一定为实. 你所期望的中文打印输出都成了乱码,心在滴血.... 解决方法详细,纯属个人摸索 1.新建notepad++文件,编码方式 ...
- 关于attibutedText输出中文字符后的英文和数字进行分开解析的问题
上面的图应该很清楚 具体这个attibutedText 是做什么的就不说了 ,最初我查了资料发现有人和我一样的输出,把一个字符串的中英文分开打印出来是iOS关于UItextVIew和UIlabel的差 ...
- [转]notepad++ java编码,输出中文字符时,编译出错
呆在公司中,最近受开发手机app的几个同事影响,想学android的开发,心血来潮,挡也挡不住,说干就干,直接看教程,发现有很多关于java的语法知识不懂,于是又来学java,学习的过程中难免出现问题 ...
- notepad++ java编码,输出中文字符时,编译出错
呆在公司中,最近受开发手机app的几个同事影响,想学android的开发,心血来潮,挡也挡不住,说干就干,直接看教程,发现有很多关于java的语法知识不懂,于是又来学java,学习的过程中难免出现问题 ...
- 宽字符输出中文,Devc++解决方法
有群友问类似问题,然后我编译了一下试试: #include <stdio.h> #include <wchar.h> #include <locale.h> int ...
随机推荐
- C# 微信h5支付
相关文档 https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=9_20&index=1 需要准备 公众号ID.商户号.商家私钥 1.登 ...
- ArcEngine 数据编辑(IWorkspaceFactory)
数据编辑做过很多次,没怎么出现问题,今天出现了问题,浪费了大半天,记录一下. 问题:修改Featrue的属性,修改后停止编辑,但是没有提示是否保存修改 原因:在编辑数据的时候没有加StartEditO ...
- 代码注释规范-IDEA 配置 Java 类方法注释模板
1. 引言 团队开发时,业务模块分配的越清晰,代码注释管理越完善,越有利于后面维护,后面再管理也方便不少.另外也起着"文字砖"的作用,你懂的.注释不需要很详细,把代码块方法 ...
- Scala实践10
1.模式匹配 模式匹配是一种根据模式检查值的机制.它是switch(Java中语句)的更强大版本,它同样可以用来代替一系列if / else语句. 句法 匹配表达式具有值,match关键字和至少一个c ...
- Could not find iPhone 6 simulator
最近原来的老项目有点问题需要处理一下,运行启动命令,就报了如下错误,提示找不到iPhone 6 模拟器. react-native run-ios Owaiss-Mac:pdm owaisahmed$ ...
- ES 服务器 索引、类型仓库基类 BaseESStorage
/******************************************************* * * 作者:朱皖苏 * 创建日期:20180508 * 说明:此文件只包含一个类,具 ...
- 区间dp - 送外卖
When we are focusing on solving problems, we usually prefer to stay in front of computers rather tha ...
- SpringCloud之Eureka(注册中心集群篇)(三)
一:集群环境搭建 第一步:我们新建两个注册中心工程一个叫eureka_register_service_master.另外一个叫eureka_register_service_backup eurek ...
- MySql笔记(二)
目录 MySQL笔记(二) 一幅画,一次瞬间的回眸,就在那次画展上,那个眼神,温柔的流转,还是那干净的皮鞋,一尘不染,俊朗的眉宇性感的唇,悄悄走近,牵手一段浪漫 MySQL笔记(二) 13.条件查询 ...
- 2.Markdown学习
Makrdown学习: 1.推荐编辑器: Typora [点击跳转](https://www.typora.io/) 2.标题: #空格一级标题名 ##空格二级标题名 3.字体: 粗体:** ** H ...