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 ...
随机推荐
- django 数据库连接出现的问题
mysqlclient 1.3.3 or newer is required; you have 0.7.11: 解决方法: 将报错文件中的如下代码注释: if version < (1, 3, ...
- 图解 kubernetes scheduler 架构设计系列-初步了解
资源调度基础 scheudler是kubernetes中的核心组件,负责为用户声明的pod资源选择合适的node,同时保证集群资源的最大化利用,这里先介绍下资源调度系统设计里面的一些基础概念 基础任务 ...
- iOS多线程编程原理及实践
摘要:iOS开发中,开发者不仅要做好iOS的内存管理,而且如果你的iOS涉及多线程,那你也必须了解iOS编程中对多线程的限制,iOS主线程的堆栈大小为1M,其它线程均为512KB,且这个限制开发者是无 ...
- C#多线程与异步
1.什么是异步同步 如果一个方法被调用,调用者需要等待该方法被执行完毕之后才能继续执行,则是同步. 如果方法被调用后立刻返回,即使该方法是一个耗时操作,也能立刻返回到调用者,调用者不需要等待该方法,则 ...
- linux下解压缩文件中文乱码问题的解决
在windows上压缩的文件,是以系统默认编码中文来压缩文件.由于zip文件中没有声明其编码,所以linux上的unzip一般以默认编码解压,中文文件名会出现乱码. 虽然2005年就有人把这报告为bu ...
- pqsql 防注入
在数据库查询时经常会遇到根据传入的参数查询内容的情况,传入的参数有可能会带有恶意代码,比如or 1=1,这样where判断为true,就会返还所有的记录.为了解决这个问题,可以在参数外面包一层单引号, ...
- APICloud联合腾讯云推出“云主机解决方案“,各种福利等你拿
为了帮助开发者一站式打通云.开发.运维全流程服务,更全面提供基于自身业务情况的云服务器.数据库.存储等基础设施服务,APICloud联合腾讯云重磅推出“云主机解决方案“.开发者可通过控制台简单清晰的购 ...
- cogs 2109. [NOIP 2015] 运输计划 提高组Day2T3 树链剖分求LCA 二分答案 差分
2109. [NOIP 2015] 运输计划 ★★★☆ 输入文件:transport.in 输出文件:transport.out 简单对比时间限制:3 s 内存限制:256 MB [题 ...
- Logback源码分析
在日常开发中经常通过打印日志记录程序执行的步骤或者排查问题,如下代码类似很多,但是,它是如何执行的呢? package chapters; import org.slf4j.Logger; impor ...
- Linux.vim.多行复制、删除、剪切
复制: //单行复制+粘贴 yy + p:复制光标所处当前行, 敲p粘贴在光标处. //多行复制+粘贴 n + yy + p:复制光标所在行起以下n行(含当前行), 敲yy复制光标所处当前行, 敲p粘 ...