c语言中文网_在C语言中使用中文字符

大部分C语言教材对中文字符的处理讳莫如深,甚至只字不提,导致很多初学者认为C语言只能处理英文,而不支持中文。其实C语言是一门全球化的编程语言,它支持世界上任何一个国家的语言文化,包括中文、日语、韩语等。

中文字符的存储

正确地存储中文字符需要解决两个问题。
1) 足够长的数据类型
char 只能处理 ASCII 编码中的英文字符,是因为 char 类型太短,只有一个字节,容纳不下我大中华几万个汉字,要想处理中文字符,必须得使用更长的数据类型。一个字符在存储之前会转换成它在字符集中的编号,而这样的编号是一个整数,所以我们可以用整数类型来存储一个字符,比如 unsigned short、unsigned int、unsigned long 等。
2) 选择包含中文的字符集
C语言规定,对于汉语、日语、韩语等 ASCII 编码之外的单个字符,也就是专门的字符类型,要使用宽字符的编码方式。常见的宽字符编码有 UTF-16 和 UTF-32,它们都是基于 Unicode 字符集的,能够支持全球的语言文化。在真正实现时,微软编译器(内嵌于 Visual Studio 或者 Visual C++ 中)采用 UTF-16 编码,使用 2 个字节存储一个字符,用 unsigned short 类型就可以容纳。GCC、LLVM/Clang(内嵌于 Xcode 中)采用 UTF-32 编码,使用 4 个字节存储字符,用 unsigned int 类型就可以容纳。 对于编号较小的字符,UTF-16 采用两个字节存储;对于编号较大的字符,UTF-16 使用四个字节存储。但是,全球常用的字符也就几万个,使用两个字节存储足以,只有极其罕见,或者非常古老的字符才会用到四个字节。
微软编译器使用两个字节来存储 UTF-16 编码的字符,虽然不能囊括所有的 Unicode 字符,但是也足以容纳全球的常见字符了,基本满足了软件开发的需求。使用两个字节存储的另外一个好处是可以节省内存,而使用四个字节会浪费 50% 以上的内存。 你看,不同的编译器可以使用不同的整数类型。如果我们的代码使用 unsigned int 来存储宽字符,那么在微软编译器下就是一种浪费;如果我们的代码使用 unsigned short 来存储宽字符,那么在 GCC、LLVM/Clang 下就不够。为了解决这个问题,C语言推出了一种新的类型,叫做 wchar_t。w 是 wide 的首字母,t 是 type 的首字符,wchar_t 的意思就是宽字符类型。wchar_t 的长度由编译器决定:
  • 在微软编译器下,它的长度是 2,等价于 unsigned short;
  • 在GCC、LLVM/Clang 下,它的长度是 4,等价于 unsigned int。
wchar_t 其实是用 typedef 关键字定义的一个别名,我们会在《 C语言typedef的用法详解 》一节中深入讲解,大家暂时只需要记住,wchar_t 在不同的编译器下长度不一样。 wchar_t 类型位于 头文件中,它使得代码在具有良好移植性的同时,也节省了不少内存,以后我们就用它来存储宽字符。上节我们讲到,单独的字符由单引号 ' ' 包围,例如 'B''@''9' 等;但是,这样的字符只能使用 ASCII 编码,要想使用宽字符的编码方式,就得加上 L 前缀,例如 L'A'L'9'L'中'L'国'L'。'。 注意,加上 L 前缀后,所有的字符都将成为宽字符,占用 2 个字节或者 4 个字节的内存,包括 ASCII 中的英文字符。下面的例子演示了如何存储宽字符(注意引入 头文件):
wchar_t a = L'A';  //英文字符(基本拉丁字符)wchar_t b = L'9';  //英文数字(阿拉伯数字)wchar_t c = L'中';  //中文汉字wchar_t d = L'国';  //中文汉字wchar_t e = L'。';  //中文标点wchar_t f = L'ヅ';  //日文片假名wchar_t g = L'♥';  //特殊符号wchar_t h = L'༄';  //藏文
在以后的编程中,我们将不加 L 前缀的字符称为窄字符,将加上 L 前缀的字符称为宽字符。窄字符使用 ASCII 编码,宽字符使用 UTF-16 或者 UTF-32 编码。

宽字符的输出

putchar、printf 只能输出不加 L 前缀的窄字符,对加了 L 前缀的宽字符无能为力,我们必须使用 头文件中的宽字符输出函数,它们分别是 putwchar 和 wprintf:
  • putwchar 函数专门用来输出一个宽字符,它和 putchar 的用法类似;
  • wprintf 是通用的、格式化的宽字符输出函数,它除了可以输出单个宽字符,还可以输出宽字符串(稍后讲解)。宽字符对应的格式控制符为%lc
另外,在输出宽字符之前还要使用 setlocale 函数进行本地化设置,告诉程序如何才能正确地处理各个国家的语言文化。由于大家基础还不够,关于本地化设置的内容我们不再展开讲解,请大家先记住这种写法。如果希望设置为中文简体环境,在 Windows 下请写作:
setlocale(LC_ALL, "zh-CN");
在 Linux 和 Mac OS 下请写作:
setlocale(LC_ALL, "zh_CN");
setlocale 函数位于 头文件中,我们必须引入它。下面的代码完整地演示了宽字符的输出:
#include #include int main(){    wchar_t a = L'A';  //英文字符(基本拉丁字符)    wchar_t b = L'9';  //英文数字(阿拉伯数字)    wchar_t c = L'中';  //中文汉字    wchar_t d = L'国';  //中文汉字    wchar_t e = L'。';  //中文标点    wchar_t f = L'ヅ';  //日文片假名    wchar_t g = L'♥';  //特殊符号    wchar_t h = L'༄';  //藏文       //将本地环境设置为简体中文    setlocale(LC_ALL, "zh_CN");    //使用专门的 putwchar 输出宽字符    putwchar(a);  putwchar(b);  putwchar(c);  putwchar(d);    putwchar(e);  putwchar(f);  putwchar(g);  putwchar(h);    putwchar(L'\n');  //只能使用宽字符       //使用通用的 wprintf 输出宽字符    wprintf(        L"Wide chars: %lc %lc %lc %lc %lc %lc %lc %lc\n",  //必须使用宽字符串        a, b, c, d, e, f, g, h    );          return 0;}
运行结果: A9中国。ヅ♥༄Wide chars: A 9 中 国 。ヅ ♥ ༄

宽字符串

给字符串加上 L 前缀就变成了宽字符串,它包含的每个字符都是宽字符,一律采用 UTF-16 或者 UTF-32 编码。输出宽字符串可以使用 头文件中的 wprintf 函数,对应的格式控制符是 %ls 。下面的代码演示了如何使用宽字符串:
#include #include int main(){    wchar_t web_url[] = L"http://c.biancheng.net";    wchar_t *web_name = L"C语言中文网";       //将本地环境设置为简体中文    setlocale(LC_ALL, "zh_CN");    //使用通用的 wprintf 输出宽字符    wprintf(L"web_url: %ls \nweb_name: %ls\n", web_url, web_name);    return 0;}
运行结果: web_url: http://c.biancheng.netweb_name: C语言中文网其实,不加 L 前缀的窄字符串也可以处理中文,它和加上了 L 前缀的宽字符串有什么区别呢?我们将在下节《 C语言到底使用什么编码?谁说C语言使用ASCII码,真是荒谬! 》中详细讲解。

7a813d772cd2794258853b728f5fe934.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值