C 语言中使用多字节字符,通过 UTF-8 支持中文

C 语言默认的 char 类型是单字节字符,仅支持 ASCII 码。但是 ISO C90 标准开始,定义了 wchar_t 类型用于支持多字节字符(头文件 wchar.h)。
这一版标准中还定义了本地化和国际化相关的头文件 locale.h,可以通过其中的 setlocale 函数设置使用的字符集编码,一般用 UTF-8 足够了。

每一种语言都分为内部编码(程序代码中使用的)和外部编码(例如打开的文件,接受的网络数据)。

要写 C 代码,最小的字符集就是 ASCII 码,也就是 C 程序初始化时默认的编码。此时 locale 设置成 C。如果需要输出多字节字符,可以在 main 函数中修改编码方式。

宽字节字符串有一系列单独的处理函数,通常以 wcs (wide character sequence 宽字符序列)开头,例如 wcslen()wcscmp() 等。注意不要混用单字节字符处理函数和多字节字符处理函数,例如 printf 和 wprintf。对于多字节字符,在用 wprintf 输出时,lc 表示宽字节字符,ls 表示宽字节字符串。

操作系统也有本地化设置的相关参数,例如对于 Linux 可以用 locale 命令查看。其中 LANG 会设置到环境变量中,这个需要跟 C 语言中设置的编码一致(对于下面的编码,C 语言中可以设置为 C.UTF-8):

$ locale
LANG=en_US.UTF-8
LANGUAGE=
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC=zh_CN.UTF-8
LC_TIME=zh_CN.UTF-8
LC_COLLATE="en_US.UTF-8"
LC_MONETARY=zh_CN.UTF-8
LC_MESSAGES="en_US.UTF-8"
LC_PAPER=zh_CN.UTF-8
LC_NAME=zh_CN.UTF-8
LC_ADDRESS=zh_CN.UTF-8
LC_TELEPHONE=zh_CN.UTF-8
LC_MEASUREMENT=zh_CN.UTF-8
LC_IDENTIFICATION=zh_CN.UTF-8
LC_ALL=
#include <stdio.h>
#include <wchar.h>
#include <locale.h>

int main(void) {
    setlocale(LC_ALL, "C.UTF-8"); 	// 设置字符集,必须与本机编码后缀一致,例如 en_US.UTF-8
    wchar_t* s = L"你好";			// 字符串前加 L 转为宽字节字符串
    wprintf(L"你好c test %S", s);	// wprintf 函数中,格式字符串也必须是宽字节的
//    printf("你好c test %S", s);		// 这里有时也可以正常输出,但可能导致异常
//    printf("你好c test %ls", s);

    return 0;
}

获取输入流的 UTF-8 数据

#include <stdio.h>
#include <wchar.h>
#include <locale.h>

int main() {
	setlocale(LC_ALL, "C.UTF-8");
	wchar_t c;
	wscanf(L"%lc", &c);
	wprintf(L"%lc\n", c);
//	printf("换人"); 		// 还是不用混用 printf wprintf
	return 0;
}
  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值