编程进阶网编程进阶网
  • 基础组成体系
  • 程序编程原理
  • 异常和IO系统
  • 六大设计原则
  • 设计模式导读
  • 创建型设计模式
  • 结构型设计模式
  • 行为型设计模式
  • 设计模式案例
  • 面向对象思想
  • 基础入门
  • 高级进阶
  • JVM虚拟机
  • 数据集合
  • Java面试题
  • C语言入门
  • C综合案例
  • C标准库
  • C语言专栏
  • C++入门
  • C++综合案例
  • C++专栏
  • HTML
  • CSS
  • JavaScript
  • 前端专栏
  • Swift
  • iOS入门
  • 基础入门
  • 开源库解读
  • 性能优化
  • Framework
  • 方案设计
  • 媒体音视频
  • 硬件开发
  • Groovy
  • 常用工具
  • 大厂面试题
  • 综合案例
  • 网络底层
  • Https
  • 网络请求
  • 故障排查
  • 专栏
  • 数组
  • 链表
  • 栈
  • 队列
  • 树
  • 递归
  • 哈希
  • 排序
  • 查找
  • 字符串
  • 其他
  • Bash脚本
  • Linux入门
  • 嵌入式开发
  • 代码规范
  • Markdown
  • 开发理论
  • 开发工具
  • Git管理
  • 百宝箱
  • 开源协议
  • 技术招聘
  • 测试经验
  • 职场提升
  • 技术模版
  • 关于我
  • 目标清单
  • 学习框架
  • 育儿经验
  • 我的专栏
  • 底层能力
  • 读书心得
  • 随笔笔记
  • 职场思考
  • 中华历史
  • 经济学故事
  • 基础组成体系
  • 程序编程原理
  • 异常和IO系统
  • 六大设计原则
  • 设计模式导读
  • 创建型设计模式
  • 结构型设计模式
  • 行为型设计模式
  • 设计模式案例
  • 面向对象思想
  • 基础入门
  • 高级进阶
  • JVM虚拟机
  • 数据集合
  • Java面试题
  • C语言入门
  • C综合案例
  • C标准库
  • C语言专栏
  • C++入门
  • C++综合案例
  • C++专栏
  • HTML
  • CSS
  • JavaScript
  • 前端专栏
  • Swift
  • iOS入门
  • 基础入门
  • 开源库解读
  • 性能优化
  • Framework
  • 方案设计
  • 媒体音视频
  • 硬件开发
  • Groovy
  • 常用工具
  • 大厂面试题
  • 综合案例
  • 网络底层
  • Https
  • 网络请求
  • 故障排查
  • 专栏
  • 数组
  • 链表
  • 栈
  • 队列
  • 树
  • 递归
  • 哈希
  • 排序
  • 查找
  • 字符串
  • 其他
  • Bash脚本
  • Linux入门
  • 嵌入式开发
  • 代码规范
  • Markdown
  • 开发理论
  • 开发工具
  • Git管理
  • 百宝箱
  • 开源协议
  • 技术招聘
  • 测试经验
  • 职场提升
  • 技术模版
  • 关于我
  • 目标清单
  • 学习框架
  • 育儿经验
  • 我的专栏
  • 底层能力
  • 读书心得
  • 随笔笔记
  • 职场思考
  • 中华历史
  • 经济学故事
  • 01.stdio.h标准库
  • 02.stdlib.h标准库
  • 03.stdint.h标准库
  • 04.signal.h信号处理
  • 05.assert.h标准库
  • 06.ctype.h标准库
  • 07.errno.h错误处理
  • 08.float.h标准库
  • 09.inttypes.h标准库
  • 10.iso646.h标准库
  • 11.limits.h标准库
  • 12.locale.h标准库
  • 13.math.h函数库
  • 14.stdarg.h标准库
  • 15.stdbool.h标准库
  • 16.stddef.h标准库
  • 17.string.h标准库
  • 18.time.h时间库
  • 19.wchar.h标准库
  • 20.wctype.h标准库

19.wchar.h标准库

宽字符使用两个或四个字节表示一个字符,导致 C 语言常规的字符处理函数都会失效。wchar.h 定义了许多宽字符专用的处理函数。

类型别名和宏

wchar.h 定义了一个类型别名 wint_t,表示宽字符对应整数值。

wchar.h 还定义了一个宏 WEOF,表示文件结束字符 EOF 的宽字符版。

btowc(),wctob()

btowc()将单字节字符转换为宽字符,wctob()将宽字符转换为单字节字符。

wint_t btowc(int c);
int wctob(wint_t c);

btowc()返回一个宽字符。如果参数是 EOF,或转换失败,则返回 WEOF。

wctob()返回一个单字节字符。如果参数是 WEOF,或者参数宽字符无法对应单个的单字节字符,则返回 EOF。

下面是用法示例。

wint_t wc = btowc('B'); 

// 输出宽字符 B
wprintf(L"Wide character: %lc\n", wc);

unsigned char c = wctob(wc);

// 输出单字节字符 B
wprintf(L"Single-byte character: %c\n", c);

fwide()

fwide()用来设置一个字节流是宽字符流,还是多字节字符流。

如果使用宽字符专用函数处理字节流,就会默认设置字节流为宽字符流,否则就需要使用fwide()显式设置。

int fwide(FILE* stream, int mode);

它接受两个参数,第一个参数是文件指针,第二个参数是字节流模式,有三种选择。

  • 0:字节流模式保持原样。
  • -1(或其他负值):设为多字节字符流。
  • 1(或其他正值):设为宽字符流。

fwide()的返回值也分成三种情况:如果是宽字符流,返回一个正值;如果是多字节字符流,返回一个负值;如果是普通字符流,返回0。

一旦设置了字节流模式,就无法再更改。

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

int main(void) {
  wprintf(L"Hello world!\n");
  int mode = fwide(stdout, 0);
  wprintf(L"Stream is %ls-oriented\n", mode < 0 ? L"byte" : L"wide");
}

上面示例中,wprintf()将字节流隐式设为宽字符模式,所以fwide(stdout, 0)的返回值大于零。

宽字符专用函数

下面这些函数基本都是 stdio.h 里面的字符处理函数的宽字符版本,必须使用这些函数来操作宽字符。

  • fgetwc() 从宽字符流中获取宽字符,对应 fgetc()。
  • fgetws() 从宽字符流中读取宽字符串,对应 fgets()。
  • fputwc() 将宽字符写入宽字符流,对应 fputc()。
  • fputws() 将宽字符串写入宽字符流,对应 fputs()。
  • fwprintf() 格式化宽输出到宽字符流,对应 fprintf()。
  • fwscanf() 来自宽字符流的格式化宽字符输入,对应 fscanf()。
  • getwchar() 从 stdin 获取一个宽字符,对应 getchar()。
  • getwc() 从 stdin 获取一个宽字符,对应 getc()。
  • putwchar() 写一个宽字符到 stdout,对应 putchar()。
  • putwc() 写一个宽字符到 stdout,对应 putc()。
  • swprintf() 格式化宽输出到宽字符串,对应 sprintf()。
  • swscanf() 来自宽字符串的格式化宽输入,对应 sscanf()。
  • ungetwc() 将宽字符推回输入流,对应 ungetc()。
  • vfwprintf() 可变参数的格式化宽字符输出到宽字符流,对应 vfprintf()。
  • vfwscanf() 来自宽字符流的可变参数格式化宽字符输入,对应 vfscanf()。
  • vswprintf() 可变参数的格式化宽字符输出到宽字符串,对应 vswprintf()。
  • vswscanf() 来自宽字符串的可变参数格式化宽字符输入,对应 vsscanf()。
  • vwprintf() 可变参数格式化宽字符输出,对应 vprintf()。
  • vwscanf() 可变参数的格式化宽字符输入,对应 vscanf()。
  • wcscat() 危险地连接宽字符串,对应 strcat()。
  • wcschr() 在宽字符串中查找宽字符,对应 strchr()。
  • wcscmp() 比较宽字符串,对应 strcmp()。
  • wcscoll() 比较两个考虑语言环境的宽字符串,对应 strcoll()。
  • wcscpy() 危险地复制宽字符串,对应 strcpy()。
  • wcscspn() 不是从宽字符串前面开始计算字符,对应 strcspn()。
  • wcsftime() 格式化的日期和时间输出,对应 strftime()。
  • wcslen() 返回宽字符串的长度,对应 strlen()。
  • wcsncat() 更安全地连接宽字符串,对应 strncat()。
  • wcsncmp() 比较宽字符串,长度有限,对应 strncmp()。
  • wcsncpy() 更安全地复制宽字符串,对应 strncpy()。
  • wcspbrk() 在宽字符串中搜索一组宽字符中的一个,对应 strpbrk()。
  • wcsrchr() 从末尾开始在宽字符串中查找宽字符,对应 strrchr()。
  • wcsspn() 从宽字符串前面的集合中计算字符,对应 strspn()。
  • wcsstr() 在另一个宽字符串中找到一个宽字符串,对应 strstr()。
  • wcstod() 将宽字符串转换为 double,对应 strtod()。
  • wcstof() 将宽字符串转换为 float,对应 strtof()。
  • wcstok() 标记一个宽字符串,对应 strtok()。
  • wcstold() 将宽字符串转换为 long double,对应 strtold()。
  • wcstoll() 将宽字符串转换为 long long,对应 strtoll()。
  • wcstol() 将宽字符串转换为 long,对应 strtol()。
  • wcstoull() 将宽字符串转换为 unsigned long long,对应 strtoull()。
  • wcstoul() 将宽字符串转换为 unsigned long,对应 strtoul()。
  • wcsxfrm() 转换宽字符串以根据语言环境进行比较,对应 strxfrm()。
  • wmemcmp() 比较内存中的宽字符,对应 memcmp()。
  • wmemcpy() 复制宽字符内存,对应 memcpy()。
  • wmemmove() 复制宽字符内存,可能重叠,对应 memmove()。
  • wprintf() 格式化宽输出,对应 printf()。
  • wscanf() 格式化宽输入,对应 scanf()。

多字节字符专用函数

wchar.h 也定义了一些多字节字符的专用函数。

  • mbsinit() 判断 mbstate_t 是否处于初始转换状态。
  • mbrlen() 给定转换状态时,计算多字节字符串的字节数,对应 mblen()。
  • mbrtowc() 给定转换状态时,将多字节字符转换为宽字符,对应 mbtowc()。
  • wctombr() 给定转换状态时,将宽字符转换为多字节字符,对应 wctomb()。
  • mbsrtowcs() 给定转换状态时,将多字节字符串转换为宽字符串,对应 mbstowcs()。
  • wcsrtombs() 给定转换状态时,将宽字符串转换为多字节字符串,对应 wcstombs()。
贡献者: yangchong211
上一篇
18.time.h时间库
下一篇
20.wctype.h标准库