字符集
时间:2023-08-26
本文章向大家介绍字符集,主要内容包括一、源代码层面、二、可执行程序层面(源程序字符集->可执行程序字符集)、三、WindowsAPI层面、四、杂项&总结、使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
操作系统 Windows
本地字符集(MBCS) GBK
编译器: VC8、VC6、DEV-C++(gcc)
实验字符
‘我’
GBK 字符编码 0xD2CE
UNICODE 字符编码 0x6211
‘a’
GBK 字符编码 0x61
UNICODE 字符编码 0x0061
一、源代码层面
VC81. 文件首两个字节为 0xFF 0xFE(文本文件开头几个字节标识了源文件使用的字符集,开头为0xFF 0xFE表示使用的是UNICODE字符集),所以源文件以UNICODE方式保存,‘我’字符编码为0x6211,‘a’字符编码为0x0061;
VC6
1. 使用本地字符集GBK保存源程序,‘我’字符编码为0xD2CE,‘a’字符编码为0x0061;
DEV-C++(gcc)
1. 使用本地字符集GBK保存源程序,‘我’字符编码为0xD2CE,‘a’字符编码为0x0061;
二、可执行程序层面(源程序字符集->可执行程序字符集)
VC81. 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和编译器默认字符集一致,所以没有出现乱码问题。
三、WindowsAPI层面
VC81. 如果编译参数配置了UNICODE则API被解释为调用UNICODE版本的API(带标记W的API,这里W代表UNICODE字符的含义)。
2. 如果编译参数没有配置UNICODE则API被解释为调用单字符编码版本的API(带标记A的API)。
VC6
同VC8。
DEV-C++(gcc)
同VC8。
四、杂项&总结
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字符)。
原文地址:https://www.cnblogs.com/yilang/p/16501114.html
- python常见模块之random模块
- P2756 飞行员配对方案问题
- P1151 子数整数
- python常见模块之time模块
- U10783 名字被和谐了
- BZOJ 1174: [Balkan2007]Toponyms
- 1355: [Baltic2009]Radio Transmission
- Equation Group(方程式组织)
- Python中下划线---完全解读
- python常见模块之collections模块
- MYSQL之库操作
- 实战-如何获取安卓iOS上的微信聊天记录、通过Metasploit控制安卓
- lightswitch binding custom control
- 3339: Rmq Problem
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- iOS 代码染色原理及技术实践
- 微信小程序【常用组件及自定义组件】
- 虚拟机字节码执行引擎,JVM的马达图,是爱情呀
- 微信小程序【浅提WXSS样式】
- Kubernetes Liveness and Readiness Probes
- Magicodes.IE 2.3重磅发布——.NET Core开源导入导出库
- pytest文档59-运行未提交git的用例(pytest-picked)
- pytest文档57-单元测试代码覆盖率(pytest-cov)
- pytest文档58-随机执行测试用例(pytest-random-order)
- Kubernetes探针踩坑记
- 大揭秘| 我司项目组Gitlab Flow && DevOps流程
- 离线安装Superset 0.37(截图详细版)
- 如何高速转储、索引和第7层网络流量过滤?
- 爬虫 | JS逆向某验滑动加密(二)
- 闲聊 Kotlin-Native (0) - 我们为什么应该关注一下 Kotlin Native?