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 ...
随机推荐
- FactoryMethodPattern(工厂方法模式)-----Java/.Net
也就是工厂方法(FactoryMethod)模式允许将产品类的实例化推迟到具体的创建者子类,由创建者子类决定实例化哪一个产品类.我们同样以汽车的生产作为讲解该模式的例子,因为汽车生产从宏观上来说也是特 ...
- delphi7 如何描述窗体上的全部控件
在delphi开发中,经常需要用到窗体中控件的name名来进行对象方法或属性的调用,所以如何对delphi窗体进行简洁,清楚,完整的描述就很重要.最好能不看界面也能进行界面编码,具体如下表所示: xx ...
- js中的事件委派
在介绍JS中事件委派之前先来看看一个简单的需求:为每一个超链接绑定一个单击响应函数并在控制台打印一句话,内容是:” a 标签的单击响应函数“.下面是这个需求的代码: <!DOCTYPE html ...
- Tomcat黑窗口中对于中文乱码问题的解决
存在的问题: 如标题,下图所示,启动tomcat时黑窗口中中文乱码,影响查看程序打印信息 解决方案: tomcat安装/解压目录中,conf 文件夹下 logging.properties 文件中,代 ...
- 【转】离散傅里叶变换-DFT(FFT)基础
转:https://blog.csdn.net/zhangxz259/article/details/81627341 什么是离散傅里叶变换 matlab例子 本文是从最基础的知识开始讲解,力求用最通 ...
- sparkstreaming消费kafka后bulk到es
不使用es-hadoop的saveToES,与scala版本冲突问题太多.不使用bulkprocessor,异步提交,es容易oom,速度反而不快.使用BulkRequestBuilder同步提交. ...
- vue不常用到的v-model修饰符
v-model的input事件同步输入框的数据根据输入的内容实时改变.v-model.lazy则是与change事件同步,即失去焦点或是回车才更新 v-model.number 将输入的数字转换为Nu ...
- 迭代器使用过程中为什么抛出ConcurrentModificationException
出现的场景:在迭代器对集合进行遍历的同时,集合本身进行变更操作(add(), remove(), set()). 当正常调用时: import java.util.ArrayList; import ...
- js删除数组的某个元素
最近在刷算法题,我是用js语言去写的,其中一题需要删除数组的某个元素,查了一下资料,总结一下 使用splice()方法 array.splice(start[, deleteCount[, item1 ...
- 如何优雅的用策略模式,取代臃肿的 if-else 嵌套,看这篇就够了
经常听同事抱怨,订单来源又加了一种,代码又要加一层if-else判断,光判断订单来源的if-else就好几百行代码,代码我都不想看了,相信很多同行都有过这样的感受! Java的二十几种设计模式背的滚瓜 ...