C语言中宽字符和多字节字符

简介: C 语言原本是在英文环境中设计的,主要的字符集是7 位的ASCII 码。从此开始,8 位的byte(字节)变成最常见的字符编码单位,但是国际化软件必须能够表示不同的字符,而这些字符数量庞大,无法使用一个字节编码,于是世界上使用各式 各样多字节的字符编码集合已经有数十年了,比如用来表示“非拉丁字母”以及“非字母”的中、日、韩文字系统。

C 语言原本是在英文环境中设计的,主要的字符集是7 位的ASCII 码。从此开始,8 位的byte(字节)变成最常见的字符编码单位,但是国际化软件必须能够表示不同的字符,而这些字符数量庞大,无法使用一个字节编码,于是世界上使用各式 各样多字节的字符编码集合已经有数十年了,比如用来表示“非拉丁字母”以及“非字母”的中、日、韩文字系统。在1994 年,“Normative Addendum 1”(基准增补一)的采用,让ISO C 可以标准化两种表示大型字符集的方法:宽字符(wide character,该字符集内每个字符使用相同的位长)以及多字节字符(multibyte character,每个字符可以是一到多个字节不等,而某个字节序列的字符值由字符串或流(stream)所在的环境背景决定)。
注 意: 虽然C现在提供抽象机制,可以处理和转换不同种类的编码集合,但语言本身并没有定义或指定任何编码集合,或任何字符集(除前一节提到的基本源代码字符集和 基本运行字符集外)。换句话说,这部分是由个别的实现版本指定如何编码宽字符,以及要支持什么类型的多字节字符编码机制。
自从1994 年的增补之后,C 不只提供char类型,还提供wchar_t类型(宽字符),此类型定义在stddef.h 头文件中。wchar_t 类型足以表示某个实现版本扩展字符集的任何元素。
虽然C 标准没有支持Unicode 字符集,许多实现版本使用Unicode 转换格式UTF-16 和UTF-32(参考http://www.unicode.org) 来处理宽字符。Unicode 标准和ISO/IEC 10646标准相当接近,而且是许多既有字符集(包括7 位的ASCII)的超集。如果遵循Unicode标准,wchar_t类型至少是16或32位长,而wchar_t类型的一个值就代表一个Unicode 字符。比方说,下列的定义将变量wc 初始化为希腊字母α。

wchar_t wc = '"x3b1';  
此 转义符以“"x”起头,后面接着十六进制的数字,会将这个数字所代表的字符赋值到变量中。在这个例子中,此字符是小写的alpha。在多字节字符集中,每 个字符的编码宽度都不等,可以是一个字节,也可以是多个字节。源代码字符集和运行字符集都可能包含多字节字符,如果真的包含多字节字符的话,那么基本字符 集中的每个字符都只会占用一个字节(完全没有多字节的字符),空字符是唯一的例外,空字符可能会占用任意个数的字节(但这些字节内全部的位都必须为0)。 多字节字符可以被用于字符的常量、字符串字面值(string literal)、标识符(identifier)、注释(comment),以及头文件。许多的多字节字符集被设计来支持特定国家的语言,例如JIS 字符集(日本业界标准,Japanese Industrial Standard)。多字节UTF-8 字符集是由Unicode Consortium(万国码联盟)定义的,可以表示Unicode 字符集的所有字符。
UTF-8 字符所使用的空间大小从一个字节到四个字节都有可能。多字节字符和宽字符(也就是wchar_t)的主要差异在于宽字符占用的字节数目都一样,而多字节字符的字节数目不等,这样的表示方式使得多字节字符串比宽字符串更难处理。
比 方说,即使字符'A'可以用一个字节来表示,但是要在多字节的字符串中找到此字符,就不能使用简单的字节比对,因为即使在某个位置找到相符合的字节,此字 节也不见得是一个字符,它可能是另一个不同字符的一部分。然而,多字节字符相当适合用来将文字存储成文件(参见第13 章)。
C 提供了一些标准函数,可以将多字节字符转换为wchar_t,或将宽字符转换为多字节字符。比方说,如果C 编译器使用Unicode 标准的UTF-16 和UTF-8,那么下面调用wctomb()函数就可以获得字符α 的多字节表示方式(注:wctomb = wide character to multibyte)。
wchar_t wc = L'"x3B1'; // 小写的希腊字母alpha,α

        

        char mbStr[10] = "";

        

        int nBytes = 0;

        

        nBytes = wctomb( mbStr, wc );   

在调用此函数之后,mbStr数组会得到多字节的字符,在这个例子中,也就是""xCE"xB1"符号。此wctomb()函数的返回值是“所需要 的字节个数”,在这个例子中,被赋值到变量nBytes 的值是2,意思是:希腊小写字母alpha 在多字节字符中需要占用两个字节。

目录
相关文章
|
1月前
|
存储 算法 C语言
【C语言】字符常量详解
字符常量是C语言中处理字符数据的重要工具。通过单引号括起一个字符,我们可以方便地使用字符常量进行字符判断、字符运算和字符串处理等操作。理解字符常量的表示方法、使用场景和ASCII码对应关系,对于编写高效的C语言程序至关重要。
155 11
|
1月前
|
存储 C语言 开发者
【C语言】格式化输出占位符及其标志字符详解(基于ISO/IEC 9899:2024)
在C语言中,格式化输出通过 `printf` 函数等格式化输出函数来实现。格式说明符(占位符)定义了数据的输出方式,标准ISO/IEC 9899:2024(C23)对这些格式说明符进行了详细规定。本文将详细讲解格式说明符的组成部分,包括标志字符、宽度、精度、长度修饰符和类型字符,并适当增加表格说明。
44 6
|
3月前
|
C语言
C语言字符(串)函数
C语言字符(串)函数
|
3月前
|
存储 安全 编译器
深入C语言库:字符与字符串函数模拟实现
深入C语言库:字符与字符串函数模拟实现
|
4月前
|
存储 C语言
【C语言基础考研向】10 字符数组初始化及传递和scanf 读取字符串
本文介绍了C语言中字符数组的初始化方法及其在函数间传递的注意事项。字符数组初始化有两种方式:逐个字符赋值或整体初始化字符串。实际工作中常用后者,如`char c[10]="hello"`。示例代码展示了如何初始化及传递字符数组,并解释了为何未正确添加结束符`\0`会导致乱码。此外,还讨论了`scanf`函数读取字符串时忽略空格和回车的特点。
122 8
|
3月前
|
C语言
C语言常见字符函数和字符串函数精讲
C语言常见字符函数和字符串函数精讲
|
4月前
|
存储 人工智能 C语言
C语言程序设计核心详解 第六章 数组_一维数组_二维数组_字符数组详解
本章介绍了C语言中的数组概念及应用。数组是一种存储同一类型数据的线性结构,通过下标访问元素。一维数组定义需指定长度,如`int a[10]`,并遵循命名规则。数组元素初始化可使用 `{}`,多余初值补0,少则随机。二维数组扩展了维度,定义形式为`int a[3][4]`,按行优先顺序存储。字符数组用于存储字符串,初始化时需添加结束符`\0`。此外,介绍了字符串处理函数,如`strcat()`、`strcpy()`、`strcmp()` 和 `strlen()`,用于拼接、复制、比较和计算字符串长度。
106 4
|
5月前
|
编译器 C语言
【C语言小知识】ctype.h系列的字符函数
【C语言小知识】ctype.h系列的字符函数
|
5月前
|
C语言
【C语言篇】字符和字符串以及内存函数详细介绍与模拟实现(下篇)
perror函数打印完参数部分的字符串后,再打印⼀个冒号和⼀个空格,再打印错误信息。
70 0
|
5月前
|
存储 安全 编译器
【C语言篇】字符和字符串以及内存函数的详细介绍与模拟实现(上篇)
当然可以用scanf和printf输入输出,这里在之前【C语言篇】scanf和printf万字超详细介绍(基本加拓展用法)已经讲过了,这里就不再赘述,主要介绍只针对字符的函数.
62 0