扩展字符支持
作者:追风剑情 发布于:2020-7-16 9:29 分类:C
C语言最初并不是作为国际编译语言设计的,其字符的选择或多或少是基于标准的美国键盘。但是,随着后来C在世界范围内越来越流行,不得不扩展来支持不同且更大的字符集。
三字符序列
有些键盘没有C中使用的所有符号,因此C提供了一些由三个字符组成的序列( 即三字符序列)作为这些符号的替换表示。
三字符序列 | |||||
三字符序列 | 符号 | 三字符序列 | 符号 | 三字符序列 | 符号 |
??= | # | ??( | [ | ??/ | \ |
??) | ] | ??' | ^ | ??< | { |
??! | | | ??> | } | ??- | ~ |
??=include会变成这样:??=define LIM 100 int main() ??< int q??(LIM??); printf("More to come.??\n"); ??>
#include当然,要在编译器中设置相关选项才能激活这个特性。#define LIM 100 int main() { int q[LIM]; printf("More to come.\n"); }
双字符
意识到三字符系统很笨拙,C99提供了双字符(digraph),可以使用它们来替换某些标准C标点符号。
双字符 | |||||
双字符 | 符号 | 双字符 | 符号 | 双字符 | 符号 |
<: | [ | :> | ] | <% | { |
%> | } | %: | # | %:%: | ## |
与三字符不同的是,不会替换双引号中的双字符。因此,下面的代码:
%:include会变成这样%:define LIM 100 <% int q<:lim:>; printf("More to come.:>"); %>
#include#define LIM 100 { int q[LIM]; printf("More to come.:>"); // :>是字符串的一部分 }
可选拼写:iso646.h
使用三字符序列可以把||运算符写成??!??!,这看上去比较混乱。C99通过iso646.h头文件提供了可展开运算符的宏。C标准把这些宏称为可选拼写(alternative spelling)。如果包含了iso.646.h头文件,以下代码:
if (x == M1 or x == M2) x and_eq 0xFF; 可展开了下面的代码: if (x == M1 || x == M2) x &= 0xFF;
多字节字符
C标准把多字节字符描述为一个或多个字节的序列,表示源环境或执行环境中的扩展字符集成员。源环境指的是编写源代码的环境,执行环境指的是用户运行已编译程序的环境。这两个环境不同。例如,可以在一个环境中开发程序,在另一个环境中运行该程序。扩展字符集是C语言所需的基本字符集的超集。
有些实现会提供扩展字符集,方便用户通过键盘输入与基本字符集不对应的字符。这些字符可用于字符串字面量和字符常量中,也可出现在文件中。有些实现会提供与基本字符集等效的多字节字符,可替换三字符和双字符。
例如,德国的一个实现也许会允许用户在字符串中使用日耳曼元音字符:
puts("eins zwei drei vier fünf");
一般而言,程序可使用的扩展字符集团本地化设置而异。
通用字符名(UCN)
多字节字符可以用在字符串中,但是不能用在标识符中。C99新增了通用字符名(UCN),允许用户在标识名中使用扩展字符集中的字符。系统扩展了转义序列的概念,允许编码ISO/IEC 10646标准中的字符。该标准和统一码(Unicode)关系密切。
有两种形式的UCN序列。第1种形式是\u hexquard,其中hexquard是一个4位的十六进制数序列(如,\u00F6)。第2种形式是\U hexquardhexquard,如\U0000AC01。因为十六进制每一位上的数对应4位,\u形式可用于16位整数表示的编码,\U形式可用于32位整数表示的编码。
如果系统实现了UCN,而且包含了扩展字符集中所需的字符,就可以在字符串、字符常量和标识符中使用UCN:
wchar_t value\u00F6\u00F8 = L'\u00f6';
统一码和ISO 10646
统一码为表示不同的字符集提供了一种解决方案,可以根据类型为大量字符和符号制定标准的编号系统。例如,ASCII码被合并为统一码的子集,因此美国拉丁字符(如A~Z)在这两个系统中的编码相同。但是,统一码还合并了其他拉丁字符(如,欧洲语言中使用的一些字符)和其他语言中的字符,包括希腊文、西里尔字母、希伯来文、切罗基文、阿拉伯文、泰文、孟加拉文和形意文字(如中文和日文)。到目前为止,统一码表示的符号超过了110000个,而且仍在发展中。欲了解更多细节,请查阅统一码联合站点:http://www.unicode.org
统一码为每个字符分配一个数字,这个数字称为代码点(code point)。典型的统一码代码点类似:U-222B。U表示该字符是统一字符,222B是表示该字符的一个十六进制数,在这种情况下,表示积分号。
国际标准化组织(ISO)组建了一个团队开发ISO 10646和标准编码的多语言文本。ISO 10646团队和统一码团队从1991年开始合作,一直保持两个标准的相互协调。
宽字符
C99为使用宽字符提供更多支持,通过wchar.h和wctype.h库包含了更多大型字符集。这两个头文件把wchar_t定义为一种整型类型,其确切的类型依赖实现。该类型用于储存扩展字符集中的字符,扩展字符集是基本字符集的超集。根据定义,char类型足够处理基本字符集,而wchar_t类型则需要更多位才能储存更大范围的编码值。例如,char可能是8位字节,wchar_t可能是16位的unsigned short。
用L前缀标识宽字符常量和字符字面量,用%lc和%ls显示宽字符数据: wchar_t wch = L'I'; wchar_t w_arr[200] = L"am wide!"; printf("%lc %ls\n", wch, w_arr);例如,如果把wchar_t实现为2字节单元,'I'的1字节编码应储存在wch的低位字节。不是标准字符集中的字符可能需要两个字节储存字符编码。例如,可以使用通用字符编码表示超出char类型范围的字符编码:
wchar_t w = L'\u00E2'; /* 16位编码值 */ 内含wchar_t类型值的数组可用于储存宽字符串,每个元素储存一个宽字符编码。编码值为0的wchar_t值是空字符的wchar_t类型等价字符。该字符被称为空宽字符(null wide character),用于表示宽字符串的结尾。
可以使用%lc和%ls读取宽字符: wchar_t wch1; wchar_t w_arr[20]; puts("Enter your grade:"); scanf("%lc", &wch1); puts("Enter your first name:"); scanf("%ls", w_arr);wchar_t头文件为宽字符提供更多支持,特别是提供了宽字符I/O函数、宽字符转换函数和宽字符串控制函数。例如,可以用fwprintf()和wprintf()函数输出,用fwscanf()和wscanf()函数输入。与一般输入/输出函数的主要区别是,这些函数需要宽字符格式字符串,处理的是宽字符输入/输出流。例如,下面的代码把信息作为宽字符显示:
wchar_t * pw = L"Points to a wide-character string"; int dozen = 12; wprintf(L"Item %d: %ls\n", dozen, pw);类似地,还有getwchar()、putwchar()、fgetws()和fputsws()函数。wchar_t头文件定义了一个WEOF宏,与EOF在面向字节的I/O中起的作用相同。该宏要求其值是一个与任何有效字符都不对应的值。因为wchar_t类型的值都有可能是有效字符,所以wchar_t库定义了一个wint_t类型,包含了所有wchar_t类型的值和WEOF的值。
该库中还有与string.h库等价的函数。例如,wcscpy(ws1, ws2)把ws1指定的宽字符串拷贝到ws2指向的宽字符数组中。类似地,wcscmp()函数比较宽字符串,等等。
wctype.h头文件新增了字符分类函数,例如,如果iswdigit()函数的宽字符参数是数字,则返回真;如果iswblank()函数的参数是空白,则返回真。空白的标准值是空格和水平制表符,分别写作L''和L'\t'。
C11标准通过uchar.h头文件为宽字符提供更多支持,为匹配两种常用的统一码格式,定义了两个新类型。第1种类型是char16_t,可储存一个16位编码,是可用的最小无符号整数类型,用于hexquard UCN形式和统一码UTF-16编码方案。
char16_t u = '\u00F6';
第2种类型是char32_t,可储存一个32位编码,最小的可用无符号整数类型。可用于hexquard UCN形式和统一码UTF-32编码方案
char 32_t u = '\U0000AC01';
前缘u和U分别表示char16_t和char32_t字符串。
char16_t ws16[11] = u"Tannh\u00E4user";
char32_t ws32[13] = U"caf\U000000E9 au lait";
注意,这两种类型比wchar_t类型更具体。例如,在一个系统中,wchar_t可以储存32位编码,但是在另一个系统中也许只能储存16位的编码。另外,这两种新类型都与C++兼容。
宽字符和多字节字符
宽字符和多字节字符是处理扩展字符集的两种不同的方法。例如,多字节字符可能是一个字节、两个字节、三个字节或更多字节,而所有的宽字符都只有一个宽度。多字节字符可能使用移位状态(移位状态是一个字节,确定如何解释后续字节);而宽字符没有移位状态。可以把多字节字符的文件读入使用标准输入函数的普通char类型数组,把宽字节的文件读入使用宽字符输入函数的宽字节数组。
C99在wchar.h库中提供了一些函数,用于多字节和宽字节之间的转换。mbrtowc()函数把多字节字符转换为宽字符,wcrtomb()函数把宽字符转换为多字节字符。类似地,mbstrtowcs()函数把多字节字符串转换为宽字节字符串,wcstrtombs()函数把宽字节字符串转换为多字节字符串。
C11在uchar.h库中提供了一些函数,用于多字节和char16_t之间的转换,以及多字节和char32_t之间的转换。
标签: C语言
日历
最新文章
随机文章
热门文章
分类
存档
- 2024年11月(3)
- 2024年10月(5)
- 2024年9月(3)
- 2024年8月(3)
- 2024年7月(11)
- 2024年6月(3)
- 2024年5月(9)
- 2024年4月(10)
- 2024年3月(11)
- 2024年2月(24)
- 2024年1月(12)
- 2023年12月(3)
- 2023年11月(9)
- 2023年10月(7)
- 2023年9月(2)
- 2023年8月(7)
- 2023年7月(9)
- 2023年6月(6)
- 2023年5月(7)
- 2023年4月(11)
- 2023年3月(6)
- 2023年2月(11)
- 2023年1月(8)
- 2022年12月(2)
- 2022年11月(4)
- 2022年10月(10)
- 2022年9月(2)
- 2022年8月(13)
- 2022年7月(7)
- 2022年6月(11)
- 2022年5月(18)
- 2022年4月(29)
- 2022年3月(5)
- 2022年2月(6)
- 2022年1月(8)
- 2021年12月(5)
- 2021年11月(3)
- 2021年10月(4)
- 2021年9月(9)
- 2021年8月(14)
- 2021年7月(8)
- 2021年6月(5)
- 2021年5月(2)
- 2021年4月(3)
- 2021年3月(7)
- 2021年2月(2)
- 2021年1月(8)
- 2020年12月(7)
- 2020年11月(2)
- 2020年10月(6)
- 2020年9月(9)
- 2020年8月(10)
- 2020年7月(9)
- 2020年6月(18)
- 2020年5月(4)
- 2020年4月(25)
- 2020年3月(38)
- 2020年1月(21)
- 2019年12月(13)
- 2019年11月(29)
- 2019年10月(44)
- 2019年9月(17)
- 2019年8月(18)
- 2019年7月(25)
- 2019年6月(25)
- 2019年5月(17)
- 2019年4月(10)
- 2019年3月(36)
- 2019年2月(35)
- 2019年1月(28)
- 2018年12月(30)
- 2018年11月(22)
- 2018年10月(4)
- 2018年9月(7)
- 2018年8月(13)
- 2018年7月(13)
- 2018年6月(6)
- 2018年5月(5)
- 2018年4月(13)
- 2018年3月(5)
- 2018年2月(3)
- 2018年1月(8)
- 2017年12月(35)
- 2017年11月(17)
- 2017年10月(16)
- 2017年9月(17)
- 2017年8月(20)
- 2017年7月(34)
- 2017年6月(17)
- 2017年5月(15)
- 2017年4月(32)
- 2017年3月(8)
- 2017年2月(2)
- 2017年1月(5)
- 2016年12月(14)
- 2016年11月(26)
- 2016年10月(12)
- 2016年9月(25)
- 2016年8月(32)
- 2016年7月(14)
- 2016年6月(21)
- 2016年5月(17)
- 2016年4月(13)
- 2016年3月(8)
- 2016年2月(8)
- 2016年1月(18)
- 2015年12月(13)
- 2015年11月(15)
- 2015年10月(12)
- 2015年9月(18)
- 2015年8月(21)
- 2015年7月(35)
- 2015年6月(13)
- 2015年5月(9)
- 2015年4月(4)
- 2015年3月(5)
- 2015年2月(4)
- 2015年1月(13)
- 2014年12月(7)
- 2014年11月(5)
- 2014年10月(4)
- 2014年9月(8)
- 2014年8月(16)
- 2014年7月(26)
- 2014年6月(22)
- 2014年5月(28)
- 2014年4月(15)
友情链接
- Unity官网
- Unity圣典
- Unity在线手册
- Unity中文手册(圣典)
- Unity官方中文论坛
- Unity游戏蛮牛用户文档
- Unity下载存档
- Unity引擎源码下载
- Unity服务
- Unity Ads
- wiki.unity3d
- Visual Studio Code官网
- SenseAR开发文档
- MSDN
- C# 参考
- C# 编程指南
- .NET Framework类库
- .NET 文档
- .NET 开发
- WPF官方文档
- uLua
- xLua
- SharpZipLib
- Protobuf-net
- Protobuf.js
- OpenSSL
- OPEN CASCADE
- JSON
- MessagePack
- C在线工具
- 游戏蛮牛
- GreenVPN
- 聚合数据
- 热云
- 融云
- 腾讯云
- 腾讯开放平台
- 腾讯游戏服务
- 腾讯游戏开发者平台
- 腾讯课堂
- 微信开放平台
- 腾讯实时音视频
- 腾讯即时通信IM
- 微信公众平台技术文档
- 白鹭引擎官网
- 白鹭引擎开放平台
- 白鹭引擎开发文档
- FairyGUI编辑器
- PureMVC-TypeScript
- 讯飞开放平台
- 亲加通讯云
- Cygwin
- Mono开发者联盟
- Scut游戏服务器引擎
- KBEngine游戏服务器引擎
- Photon游戏服务器引擎
- 码云
- SharpSvn
- 腾讯bugly
- 4399原创平台
- 开源中国
- Firebase
- Firebase-Admob-Unity
- google-services-unity
- Firebase SDK for Unity
- Google-Firebase-SDK
- AppsFlyer SDK
- android-repository
- CQASO
- Facebook开发者平台
- gradle下载
- GradleBuildTool下载
- Android Developers
- Google中国开发者
- AndroidDevTools
- Android社区
- Android开发工具
- Google Play Games Services
- Google商店
- Google APIs for Android
- 金钱豹VPN
- TouchSense SDK
- MakeHuman
- Online RSA Key Converter
- Windows UWP应用
- Visual Studio For Unity
- Open CASCADE Technology
- 慕课网
- 阿里云服务器ECS
- 在线免费文字转语音系统
- AI Studio
- 网云穿
- 百度网盘开放平台
- 迅捷画图
- 菜鸟工具
- [CSDN] 程序员研修院
- 华为人脸识别
- 百度AR导航导览SDK
- 海康威视官网
- 海康开放平台
- 海康SDK下载
- git download
交流QQ群
-
Flash游戏设计: 86184192
Unity游戏设计: 171855449
游戏设计订阅号