char,wchar_t,ACHAR,WCHAR,TCHAR五种类型字符的区别和使用的场景
五种字符串的区别
在C++编程过程中,字符串是十分常用的,但是在很多时候会遇到各种类型的字符串分不清楚,所以在这里介绍一下char,wchar_t,ACHAR,WCHAR,TCHAR五种类型的字符的区别。
char类型
单字节变量类型,最多表示256个字符。使用的字符编码格式为ANSI窄字节编码。
wchar_t类型
宽字节变量类型,它实际定义在<string.h>里:typedef unsigned short wchar_t。使用的字符编码格式为Unicode编码。
ACHAR类型
此类型是AUTODESK公司在AdAChar.h 头文件中定义的类型。当定义了AD_UNICODE(AUTODESK公司使用UNICODE宏)时为Unicode编码。
WCHAR类型
WCHAR类型和wchar_t类型没有区别。
TCHAR类型
如果定义了UNICODE宏时,编码格式为Unicode编码,否则为ANSI编码。
使用场景
这些字符串的使用的场景要根据其字符编码格式来进行说明,首先先介绍一下编码格式的区别。
编码格式介绍
ASCII格式
ASCII (American Standard Code for Information Interchange):美国信息交换标准代码是基于拉丁字母的一套电脑编码系统,主要用于显示现代英语和其他西欧语言。它是最通用的信息交换标准,并等同于国际标准 ISO/IEC 646。ASCII第一次以规范标准的类型发表是在1967年,最后一次更新则是在1986年,到目前为止共定义了128个字符。
因为是美国人为自己使用而设计的编码格式,所以其中只包含了大小写字母和数字,以及在美式英语中使用的特殊控制字符。
0~31及127为控制字符或通信专用字符,其余为可显示字符。
ASCII表
ASCII值 | 控制字符 | 转义字符(对应按键) | ASCII值 | 控制字符 | ASCII值 | 控制字符 | ASCII值 | 控制字符 |
---|---|---|---|---|---|---|---|---|
0 | 空字符 | /0 | 32 | 空格 | 64 | @ | 96 | '(开单引号) |
1 | 标题开始 | 33 | ! | 65 | A | 97 | a | |
2 | 正文开始 | 34 | " | 66 | B | 98 | b | |
3 | 正文结束 | 35 | # | 67 | C | 99 | c | |
4 | 传输结束 | 36 | $ | 68 | D | 100 | d | |
5 | 请求 | 37 | % | 69 | E | 101 | e | |
6 | 收到通知 | 38 | & | 70 | F | 102 | f | |
7 | 响铃 | 39 | ’ (闭单引号) | 71 | G | 103 | g | |
8 | 退格 | /b | 40 | ( | 72 | H | 104 | h |
9 | 水平制表符 | /t | 41 | ) | 73 | I | 105 | i |
10 | 换行键 | /n(回车) | 42 | * | 74 | J | 106 | j |
11 | 垂直制表符 | 43 | + | 75 | K | 107 | k | |
12 | 换页键 | /f | 44 | , | 76 | L | 108 | l |
13 | 回车键 | (回车) | 45 | - | 77 | M | 109 | m |
14 | 不用切换键 | 46 | . | 78 | N | 110 | n | |
15 | 启用切换键 | 47 | / | 79 | O | 111 | o | |
16 | 数据链路转义 | 48 | 0 | 80 | P | 112 | p | |
17 | 设备控制1 | 49 | 1 | 81 | Q | 113 | q | |
18 | 设备控制2 | 50 | 2 | 82 | R | 114 | r | |
19 | 设备控制3 | 51 | 3 | 83 | S | 115 | s | |
20 | 设备控制4 | 52 | 4 | 84 | T | 116 | t | |
21 | 拒绝接收 | 53 | 5 | 85 | U | 117 | u | |
22 | 同步空闲 | 54 | 6 | 86 | V | 118 | v | |
23 | 结束传输块 | 55 | 7 | 87 | W | 119 | w | |
24 | 取消 | 56 | 8 | 88 | X | 120 | x | |
25 | 媒介结束 | 57 | 9 | 89 | Y | 121 | y | |
26 | 替换 | 58 | : | 90 | Z | 122 | z | |
27 | 溢出/取消/逃离 | /e | 59 | ; | 91 | [ | 123 | { |
28 | 文件分隔符 | 60 | < | 92 | \ | 124 | 丨 | |
29 | 分组符 | 61 | = | 93 | ] | 125 | } | |
30 | 记录分隔符 | 62 | > | 94 | ^ | 126 | ~ | |
31 | 单元分隔符 | 63 | ? | 95 | _ | 127 | Delete(删除键) |
ANSI格式
ANSI格式并不是单指某种固定的字符编码,而是在不同的系统中,ANSI表示不同的编码。为使计算机支持更多语言,在ASCII编码外使用0x80~0xFFFF来编码,即扩展的ASCII编码。
美国所使用的ANSI编码实际是ASCII编码,而中国所使用的ANSI编码实际是GBK编码,韩国使用的ANSI编码是EUC-KR编码,日本使用的ANSI编码是Shift_JIS编码。
不同的ANSI编码不能互通,而这就导致了当信息在国际间交流时,无法将属于两种语言的文字,存储在同一段 ANSI 编码的文本中。给信息的传输造成了一定的困难。
Unicode格式
Unicode被称为统一码,也叫作万国码,是计算机科学领域里的一项业界标准,包括字符集、编码方案等,同时是一种双字节编码。
它解决了ANSI格式的各国文字无法互通的问题。
各种类型字符使用场景
根据以上的编码格式不同,可以分析出如果不需要接受多国语言的情景中时,char类型的字符已经足够使用了,而如果要设计到多国语言时,那么应该使用wchar_t类型的字符串。而TCHAR字符串更多用于懒得区分char类型和wchar_t类型或者要进行类型转换的场合。
一些小小的补充
1.下载的外国游戏如果无法运行的话,有可能是因为本地ANSI字符编码库无法识别中文路径导致乱码,从而无法运行,所以游戏最好下载在英文路径中。
这么一想在DLSITE上下载的日文游戏玩不了估计就是使用了日本的ANSI编码,然后自己的ANSI编码不能识别导致的吧。
2.关于字符串转换时,
char *a = "abcde";//这东西是ANSI编码的
wchar_t *b = L"abcde";//这东西是Unicode编码的
//把一段ANSI编码字符变成unicode编码的只用加一个L
wchar_t *c = _T("abcde");//这个_T也是把字符串变成Unicode编码
wchar_t *c = TEXT("abcde");//这个TEXT也是把字符串变成Unicode编码
//于是我们就有可能觉得,_T()或者TEXT()这个东西可以把各种奇奇怪怪的东西变成Unicode编码
//然后我们写下了一段憨憨的代码
_tcscmp(a,b);//然后就会提示"char *" 类型的实参与 "const wchar_t *" 类型的形参不兼容
//我们会觉得,那么就用TEXT()或者_T()把a转换成wchar_t格式的吧~
//于是你写下了
_tcscmp(_T(a),b);
//或者
_tcscmp(TEXT(a),b);
//然后就报错了,提示是:未定义标识符“La”
//然后你就会想:啊,什么鬼,我的代码中明明没有“La”呀,这是哪里来的呀?
//然后你就反应过来了,这个_T()和TEXT()实际上就是一个L字符,所以利用_T()和TEXT()不能直接转换变量的格式
参考
一文带你弄懂C++中的ANSI、Unicode和UTF8三种字符编码及相互转换
char、wchar_t、ACHAR、WCHAR、TCHAR
【C++】_T( )函数