2.1.5   多字节字符和宽字符

为了容纳可能包含大量字符的非英语字母,标准C引入了宽字符和宽字符串的概念。为了表示宽字符以及外部世界中面向字节的字符串,标准C还引入了多字节字符的概念。C89修正案1提供了扩展,以处理宽字符和多字节字符。

宽字符和宽字符串 宽字符是扩展字符集(extended character set)中的元素的二进制表示形式。它的类型是整数类型wchar_t,这个类型是在头文件stddef.h中声明的。C89修正案1添加了整数类型wint_t,它必须可以表示wchar_t类型的所有值,并且可以表示一个额外的、可以区分的非宽字符值,用WEOF表示。标准C并没有指定任何宽字符编码方案,但0这个值被保留为“空的宽字符值”。宽字符常量可以用一种特殊的常量语法来表示(第2.7.3节)。

例子

一般情况下,宽字符占据16位。因此,在32位的计算机上,wchar_t可以用short或unsigned short来表示。如果wchar_t用short表示,并且-1并不是合法的宽字符,则wint_t可以用short表示,WEOF可以用-1表示。但是,更典型的方法是用int或unsigned int表示wint_t。

如果编译器厂商选择不支持扩展字符集(美国的C编译器厂商经常采用这种做法),wchar_t可以被定义为char,“扩展字符集”就与常规的字符集相同。

宽字符串(wide string)是以一个null宽字符结尾的连续的宽字符序列。null宽字符就是表示形式为0的宽字符。除了null宽字符以及另外的WEOF之外,标准C并没有指定扩展字符集的编码方案。宽字符常量可以用特殊的字符串常量来指定(第2.7.4节)。

多字节字符 在C程序中,宽字符可以作为一个单独的单元进行操作,但大多数外部媒介(例如文件)和C源程序是基于单个字节长度的字符的。熟悉扩展字符集的程序员设计了多字节编码(multibyte encoding),这是一种区域特定的方法,在字节长度的字符序列和宽字符序列之间进行映射。

多字节字符是源字符集或执行字符集中宽字符的表示形式(它们可能具有不同的编码形式)。因此,多字节字符串是常规的C字符串,但是这些字符可以被解释为一系列的多字节字符。多字节字符的形式以及多字节字符和宽字符之间的映射取决于定义的实现方式。在编译时,这种映射是针对宽字符常量和宽字符串常量执行的,标准函数库提供了一些函数,可以在运行时执行这种映射。

多节字字符可以使用依赖状态的编码(state-depedent encoding),即多字节字符的解释可能取决于前一个出现的多字节字符。一般情况下,这种编码利用了转移字符。这是一种控制字符,属于多字节字符的一部分,用于更改当前以及后续字符的解释。在一个多字节字符序列中,当前解释被称为编码的转换状态(conversion state),或称转移状态(shift state)。开始对一个多字节字符序列进行转换时,总是使用一个可区分的初始转换(转移)状态,并且这个状态经常在转换结束时被返回。

例子

A编码(我们在这个例子中所使用的一种假设编码)是一种取决于状态的编码方案,它具有两个转移状态:“上”和“下”。↑字符把转移状态修改为“上”,↓字符把转移状态修改为“下”。“下”状态是初始状态,所有的非转移字符具有常规的解释。在“上”状态中,每个多字节字符由一对字母数字字符组成,它们以一种我们并未指定的方式定义了一个宽字符。

在下面这些字符序列中,每个序列包含了3个A编码形式的多字节字符,都从初始的转换状态开始。

***一个字符串包含了并非严格必需的转移字符。如果允许冗余的转移序列,多字节字符可以变成任意长度(例如↓↓…↓x)。除非知道转换状态位于多字节字符序列的开始,否则就无法对诸如abcdef这样的序列进行解析,它既可以表示3个也可以表示6位宽字符。

ab|?x这个序列在A编码形式下是非法的,因为在“上”转移状态中出现了非字母数字字符。a↑b这个序列是非法的,因为***一个多字节字符过早结束。

多字节字符也可以使用状态无关编码(state-independent encoding),即一个多字节字符的解释并不依赖于前一个多字节字符(尽管可能需要在一个多字节序列中从头开始寻找一个在字符串中间开始的多字节字符)。例如,C的转义字符的语法(第2.7.5节)表示一种char类型的状态独立编码,因为反斜杠字符(\)改变了它后面的一个或多个字符的解释,形成一个char类型的值。

例子

B编码是另一种假设的编码方案,它是一种状态无关编码,并使用了一个特殊的字符,用表示,用于更改它后面的非null字符的含义。在B编码方案中,下面这些字符序列各自包含了3个多字节字符:

在B编码方案中,这个序列是非法的,因为它的***并不是一个非null字符。

标准C对多字节字符设置了一些限制:

1. 标准字符集中的所有字符都必须出现在编码中。

2. 在初始的转移状态中,标准字符集中的所有单字节字符都保留正常的解释,并不影响转换状态。

3. 包含全0的字符不管是什么转移状态都被认为是null字符。多字节字符不能使用全0的字节作为它的第二个或后续的字符。

总而言之,这些规则保证多字节序列能够作为正常的C字符串(即中间不会嵌入null字符)处理。并且,没有特殊多字节编码的C字符和多字节序列一样可以得到预期的解释。

多字节字符的源代码和执行用法 多字节字符可以出现在注释、标识符、预处理器头文件名、字符串常量和字符常量中。每个注释、标识符、预处理器头文件名、字符串常量和字符常量必须以初始转移状态开始并结束,并且必须由合法的多字节字符序列组成。源代码的物理表示形式中的多字节字符在任何词法分析、预处理或甚至延续行的连接之前就被确认。

例子

一个日文文本编辑程序允许在字符串常量和注释中使用日文字符。如果文本被写入到一个字节流文件中,则日文字符将被转换为多字节序列,这对于字符串常量而言是可以接受的,可以被标准C编辑器所理解。

在预处理期间,字符串和字符常量中的字符被转换为执行字符集,然后才被解释为多字节序列。因此,在形成多字节字符时,转义序列能使用到。在这个阶段之前,程序中的注释已经被删除,因此多字节注释中的转义序列可能没有什么意义。

例子

如果源字符集和执行字符集相同,并且如果'a'的值在执行字符集为1418,那么字符串常量"aa"所包含的两个多字节字符与"\141\141"相同(B编码方案)。

参考:字符常量 第2.7.3节;注释 第2.2节;多字节转换工具 第11.7、11.8节;字符串常量 第2.7.4节;wchar_t、WEOF第11.1节;宽字符 2.7.3节;宽字符串 第2.7.4节;wint_t 第11.1节。

【责任编辑:云霞 TEL:(010)68476606】

点赞 0

c语言多字符和宽字符,2.1.5 多字节字符和宽字符相关推荐

  1. hbuilder怎么没法插入字符了_一个你所不知道的加密方式--零宽字符加密

    开门见山 什么是0宽字符? 顾名思义,就是字节宽度为0的特殊字符. 比如: 你‏‏‍‎‏‍‌​‏‌‌‌‎‎‏好 看起来是一句简单的打招呼,实际上还有隐含信息. 我们把它复制到这里 Zero Width ...

  2. C语言试题三十九之将s所指字符串中除了下标为奇数、同时ascii值也为奇数的字符外,其余的全都删除;串中剩余字符所形成的一个新串放在t所指的一个数组中。

    1. 题目 请编写一个函数function,它的功能是:将s所指字符串中除了下标为奇数.同时ascii值也为奇数的字符外,其余的全都删除:串中剩余字符所形成的一个新串放在t所指的一个数组中. 2 .温 ...

  3. C语言试题三十八之将s所指字符串中除了下标为偶数、同时ascii值也为偶数的字符外,其余的全都删除;串中剩余字符所形成的一个新串放在t所指的一个数组中。

    1. 题目 请编写一个函数function,它的功能是:将s所指字符串中除了下标为偶数.同时ascii值也为偶数的字符外,其余的全都删除:串中剩余字符所形成的一个新串放在t所指的一个数组中. 2 .温 ...

  4. C语言之字符串探究(六):sprintf——把格式化的数据写入某个字符缓冲区

    相关博文:C++之char和string字符串类探究 相关博文:C语言之数组探究(一):定义.大小.初始化.访问和三要素 相关博文:C语言之字符串探究(一):字符串与字符数组 相关博文:C语言之字符串 ...

  5. C语言编程>第十六周 ⑦ s是全部由小写字母字符和空格字符组成的字符串,由len传入字符串的长度,请补充fun函数,该函数的功能是:统计字符串s中的单词数,结果由变量len传回。

    例题:s是全部由小写字母字符和空格字符组成的字符串,由len传入字符串的长度,请补充fun函数,该函数的功能是:统计字符串s中的单词数,结果由变量len传回.每个单词之间都由空格隔开,并且字符串s开始 ...

  6. C语言学习笔记06-占位符格式、C基本类型及逃逸字符一些细节(附介绍BCD码)

    主要整理有关占位符格式与逃逸字符的一些细节 朋友们,看栗子--"BCD解码" (文末附BCD码介绍) 一个BCD数的十六进制是0x12(对应二进制表示:0001 0010),它表达 ...

  7. 【C语言】输入一行字符,分别统计出其中英文字母 空格 数字和其他字符的个数

    输入一行字符,分别统计出其中英文字母 空格 数字和其他字符的个数 #include <stdio.h> int main() {char c;int letters=0,space=0,d ...

  8. 小程序html字符,小程序从后台输出的代码为HTML实体字符如何解决?

    最近在做一个小程序的考试系统,从后台调出的数据是这个样子的 那么我遇到这个问题的时候想到的微信小程序的富文本即(wxParse),使用过wxParse的都知道,富文本必须得具体到单个的数据上才能使用, ...

  9. linux字符界面忘记登录密码,个性化修改Linux登录时的字符界面

    如果采用root账号登录编辑/etc/bashrc内容,那所有其他帐号登录都会提示相同的内容,如果想每个用户进行配置,那就去每个帐号的目录下去配置吧. 这里提供改一个文件所有帐号都能看到的个性显示内容 ...

  10. 统计从键盘输入的一行字符中小写字母,大写字母,数字字符和其它字符的个数。

    统计从键盘输入的一行字符中小写字母,大写字母,数字字符和其它字符的个数. C语言实现 vs-2019 #include<stdio.h> #include<ctype.h> i ...

最新文章

  1. 在一个Java版本上运行Eclipse IDE,但在另一个Java版本上运行
  2. 深入理解 Git 的实现原理
  3. SpringBoot 整合Shiro Ehcache
  4. 为什么深层神经网络难以训练_“用魔法击败魔法”?一群计算神经学家正借神经网络解释大脑...
  5. java序列化与深度克隆
  6. 最近一个快要结束的项目的BUG分析
  7. 重装系统后没有网卡驱动
  8. 百度搜索引擎的工作原理
  9. 计算机默认网络密码是多少,中国电信的默认服务密码是什么
  10. 皮皮虾视频抓包去水印教程原理
  11. 百度地图语音导航开发
  12. Dell戴尔笔记本电脑G15 5515 Ryzen Edition原装出厂Windows11系统恢复原厂oem系统
  13. 理解超键、候选键、主键概念及关系
  14. 如何使用iTunes与iTools导出微信聊天记录
  15. 每天一个小技巧【5】·数位板笔刷压感设置
  16. 大衣哥谷传民纷争,若和合国际收购《火火的情怀》收购价格受关注
  17. 【硬核】年底绩效面谈,涨薪,老板给加了1万块
  18. unity 正六边形网格绘制(精简版)-代码可直接复用
  19. python做神经网络识别车牌_Python与人工神经网络:使用神经网络识别手写图像介绍...
  20. 人工智能在计算机视觉方面的应用3000字,人工智能在计算机视觉及网络领域中的应用...

热门文章

  1. 外贸网站建站是什么?
  2. 解决hive表中comment中文乱码问题
  3. 【OpenGL学习笔记③】——着色器【GLSL Uniform 彩色三角形 变色正方形】
  4. java excel下拉框_Java设置Excel下拉列表
  5. 知网免费查阅、下载论文方法
  6. 设备性能测试 : 内存带宽的测试
  7. JAVA SE 003——数值
  8. 轻量级云服务器部署K3S(公网部署)
  9. 域名购买之后怎么使用
  10. win10桌面计算机打不开,win10“此电脑”双击打不开,任何文件夹都打不开