C++字符集问题终极分析(可解决乱码问题)
最近研究vc,windows的东西真是很傻瓜,啥都给你做好,有个好处就是开发方便了。
有个弊端就是完全按微软的一套进行,规则都是它定的,你得知道它的很多api,
开发出来的代码效率不高,不过却可以比较快的实现一些较好的功能,其实软件开发就应该这样
要不每个程序员都从0开始做起,那都停留在Hello层次了。其实微软的弊端主要体现在后台的封装,
开发者无法知道它的api的实现方式;或许某天微软挂了,无数程序员就得上街卖唱乞讨了,
不过软件行业老大微软可不是那么容易挂的。
vc中字符处理是一个比较重要的部分,很多初学者对这个都头痛。
某网友写的关于vc字符集的,看了下还不错,转过来有空看看。
来源:
http://blog.csdn.net/phylh/archive/2009/01/21/3847030.aspx
系统环境
操作系统 Windows XP
本地字符集(MBCS) GBK
编译器: VC8、VC6、DEV-C++(gcc)
实验字符
‘我’
GBK 字符编码 0xD2CE
UNICODE 字符编码 0x6211
‘a’
GBK 字符编码 0x61
UNICODE 字符编码 0x0061
A-源代码层面
VC8
1. 文件首两个字节为 0xFF 0xFE(文本文件开头几个字节标识了源文件使用的字符集,开头为0xFF 0xFE表示使用的是UNICODE字符集),所以源文件以UNICODE方式保存,‘我’字符编码为0x6211,‘a’字符编码为0x0061;
VC6
1. 使用本地字符集GBK保存源程序,‘我’字符编码为0xD2CE,‘a’字符编码为0x0061;
DEV-C++(gcc)
1. 使用本地字符集GBK保存源程序,‘我’字符编码为0xD2CE,‘a’字符编码为0x0061;
B-可执行程序层面(源程序字符集->可执行程序字符集)
VC8
1. VC8编译器默认的程序字符集是本地字符集GBK。
2. 编译参数#pragma setlocale(LOC)告诉编译器源代码字符集为LOC,如果不设置则为UNICODE。
3. 如果字符字面量前有L(L”我”,L”a”),并且设置了编译参数#pragma setlocale(LOC),那么编译时将发生LOC->UNICODE字符集的转换;假如没有设置则发生源代码字符集UNICODE->UNICODE的转换(相当于不发生转换),’我’的编码是0x6211,’a’的编码是0x0061。
4. 如果字符字面量前没有L,编译时发生源代码字符集UNICODE->本地字符集GBK编码的转换,’我’的编码是0xD2CE,’a’的编码是0x61。
VC6
1. VC6编译器默认的程序字符集是本地字符集GBK。
2. 编译参数#pragma setlocale(LOC)告诉编译器源代码字符集为LOC,如果不设置则为系统默认字符集GBK。
3. 如果字符字面量前有L(L”我”,L”a”),并且设置了编译参数#pragma setlocale(LOC),那么编译时将发生LOC->UNICODE字符集的转换;假如没有设置则发生源代码字符集本地GBK->UNICODE的转换,’我’的编码是0x6211,’a’的编码是0x0061。
4. 其它情况都不发生任何的字符集编码转换(源程序字符集和程序字符集一致),使用本地字符集GBK编码’,我’的编码是0xD2CE,’a’的编码是0x61。
DEV-C++(gcc)
1. DEV-C++(gcc)编译器默认的程序字符集是UTF-8。
2. #pragma setlocale对编译没有影响。
3. 如果字符字面量前有L(L”我”,L”a”),那么编译时将把字符字面量从配置字符编码GBK转换为UNICODE字符编码(L开头的字符字面量都是使用UNICODE字符编码),’我’的编码是0x6211,’a’的编码是0x0061。注:编译器参数为-finput-charset=GBK(指定源程序字符集为GBK,如果不指定编译器默认源程序字符集为UTF-8)。
4. 其它情况会发生编译器配置参数GBK->UTF-8字符集的转换,’我’的编码是0x9E88E6,’a’的编码是0x61。这种情况下使用printf打印的时候会出现乱码,由于本地字符集是GBK,但实际字符编码是UTF-8,解决方法是在程序中把UTF-8转换为本地字符集GBK然后再调用printf打印。
5. 在RH Linux系统下直接调用printf打印不会出问题,因为在该系统下默认字符集是UTF-8和编译器默认字符集一致,所以没有出现乱码问题。
C-WindowsAPI层面
VC8
1. 如果编译参数配置了UNICODE则API被解释为调用UNICODE版本的API(带标记W的API,这里W代表UNICODE字符的含义)。
2. 如果编译参数没有配置UNICODE则API被解释为调用单字符编码版本的API(带标记A的API)。
VC6
同VC8。
DEV-C++(gcc)
同VC8。
D-杂项&总结
1. VC中UNICODE编译参数只控制windows API的展开,是UNICODE方式(W标记,这里W代表UNICODE字符的含义)还是单字符方式(A标记),其它不做控制。
2. C++中字符字面量前面如果有标识L,程序运行时这个字符字面量一定UNICODE字符编码方式的宽字符(不是其它字符编码方式)。
3. C++中如果字符字面量前面没有标识L,那么程序运行时这个字符字面量一定是编译器默认字符集编码方式(VC中是GBK字符集,’我’的编码是0xD2CE,’a’的编码是0x61,DEV-C++中是UTF-8, ’我’的编码是0x9E88E6,’a’的编码是0x61)。
4. C++中wchar_t,代表宽字符(UNICODE字符只是宽字符的一种),任何宽字符都可以赋值给wchar_t,包括UNICODE字符和其它宽字符(比如GBK编码的汉字字符),所以理论上wchar_t字符仅仅只代表是宽字符,不代表一定是UNICODE字符(不过一般情况下C++实现都使用UNICODE字符)。
C++字符集问题终极分析(可解决乱码问题)的更多相关文章
- 解决乱码的方法是,在执行SQL语句之前,将MySQL以下三个系统参数设置为与服务器字符集character-set-server相同的字符集
character-set-server/default-character-set:服务器字符集,默认情况下所采用的. character-set-database:数据库字符集. characte ...
- Java Web乱码分析及解决方式(一)——GET请求乱码
引言: 在进行Web開始时.乱码是我们最常常遇到也是最主要的问题.有经验的程序员非常easy能解决,刚開始学习的人则easy被泥潭困住. 并且非常多时候.我们即使攻克了乱码问题也是不明就里.往 ...
- Code:Blocks 中文乱码问题原因分析和解决方法
下面说说修改的地方. 1.修改源文件保存编码在:settings->Editor->gernal settings 看到右边的Encoding group Box了吗?如下图所示: Use ...
- 透彻分析和解决一切javaWeb项目乱码问题
前言 乱码是我们在程序开发中经常碰到且让人头疼的一件事,尤其是我们在做javaweb开发,如果我们没有清楚乱码产生的原理,碰到乱码问题了就容易摸不着头脑,无从下手. 乱码主要出现在两部分,如下: 第一 ...
- javaweb中文中乱码分析与解决
要想解决乱码的问题, 最好的办法是先弄清楚javaweb中数据传送的原理. 本文件将简单的讲解客户端的请求和服务器响应中编码的转换过程, 以及如何解决乱码的 问题. request(req): se ...
- php 解决乱码的通用方法
一,出现乱码的原因分析 1,保存文件时候,文件有自己的文件编码,就是汉字,或者其他国语言,以什么编码来存储 2,输出的时候,要给内容指定编码,如以网页的形势输入时<meta http-equiv ...
- 左右c++与java中国的垃圾问题的分析与解决
左右c++与java中国的垃圾问题的分析与解决 DionysosLai(906391500@qq.com) 2014/8/1 问题分析: 之所以会出现中文乱码问题,归根结底在于中文的编码与英文的编码 ...
- mysql 使用set names 解决乱码问题的原理
解决乱码的方法,我们经常使用“set names utf8”,那么为什么加上这句代码就可以解决了呢?下面跟着我一起来深入set names utf8的内部执行原理 先说MySQL的字符集问题.Wind ...
- 文《左右c++与java中国的垃圾问题的分析与解决》一bug分析
文<左右c++与java中国的垃圾问题的分析与解决>一bug分析 DionysosLai(906391500@qq.com) 2014/10/21 在前几篇一博客<关于c++与jav ...
随机推荐
- iOS_XML与JSON解析
XML与JSON简介 XML 可扩展标记语言 用于标记电子文件使其具有结构性的标记语言,可以用来标记数据.定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言 易读性高,编码手写难度小,数据量 ...
- poj 1573 Robot Motion【模拟题 写个while循环一直到机器人跳出来】
...
- maven项目在打war包时出现非法字符: '\ufeff' 解决方案
问题描述: 开发工具MyEclipse 的总体开发环境,编码格式总体设置为UTF-8,在将web项目打包的时候出现:非法字符:'\ufeff" 错误. 解决方案: 利用notePad++打开 ...
- eclipse和myeclipse的配置(基于工作空间)
eclipse和myeclipse的配置是基于工作空间的,一旦工作空间发生改变,就需要重新配置. 以eclipse为例,新建工作空间后,选择Window--->Preferences: 1.在W ...
- UVA 580 Critical Mass (两次dp)
题意:一个字符串有n个位置每个位置只可能是L或者U,问你在所有可能出现的字符串中最少出现一次三个U连在一起的字符串的个数 题解:首先从左向右枚举每个位置i,保证i,i+1,i+2是U,并且i+2(不包 ...
- File类之在指定目录中查找文件
package IoDemo; import java.io.File; /** * @Title:FileDemo2 * @Description:在指定的目录中查找文件 * @author Cra ...
- Spring AOP的一个比喻和IOC的作用
aop切面编程就是在常规的执行java类中方法前或执行后加入自定义的方法.比如你本来每天都去打酱油,去,打酱油,回.现在我每天在你打酱油路上等着,你去打酱油的时候我打你一顿,回来的时候给你点糖果吃.你 ...
- Windods7+Anaconda+Tensorflow安装步骤
1.下载及安装Anaconda Anaconda是python科学计算的集成.下载Anaconda,下载地址:http://continuum.io/downloads. 由于tensorflow目前 ...
- js获取当前url的参数
可以用正则表达式获取当前url参数,例如: var t={ getQueryString:function(name){ var reg = new RegExp("(^|&)&qu ...
- 企业环境中部署 ActiveMQ
这一章讲述了怎么配置 ActiveMQ 集群.