扩展的多字节字符和宽字符工具:wchar.h(C99)

作者:追风剑情 发布于:2020-8-19 16:50 分类:C

每种实现都有一个基本字符集,要求C的char类型足够宽,以便能处理这个字符集。实现还要支持扩展的字符集,这些字符集中的字符可能需要多字节来表示。可以把多字节字符与单字节字符一起储存在普通的char类型数组,用特定的字节值指定多字节字符本身及其大小。如何解释多字节字符取决于移位状态(shift state)。在最初的移位状态中,单字节字符保留其通常的解释。特殊的多字节字符可以改变移位状态。除非显式改变特定的移位状态,否则移位状态一直保持有效。

wchar_t类型提供另一种表示扩展字符的方法,该类型足够宽,可以表示扩展字符集中任何成员的编码。用这种宽字符类型来表示字符时,可以把单字符储存在wchar_t类型的变量中,把宽字符的字符串储存在wchar_t类型的数组中。字符的宽字符表示和多字节字符表示不必相同,因为后者可能使用前者并不使用的移位状态。

wchar.h头文件提供了一些工具用于处理扩展字符的两种表示法。该头文件中定义的类型列在下表(其中有些类型也定义在其他的头文件中)。

wchar.h中定义的类型
类型 描述
wchar_t 整数类型,可表示本地化支持的最大扩展字符集
wint_t 整数类型,可储存扩展字符集的任意值和至少一个不是扩展字符集成员的值
size_t sizeof运算返回的整数类型
mbstate_t 非数组类型,可储存多字节字符序列和宽字符之间转换所需的转换状态信息
struct tm 结构类型,用于储存日历时间的组成部分

wchar.h中定义的宏
描述
NULL 空指针
WCHAR_MAX wchar_t类型可储存的最大值
WCHAR_MIN wchar_t类型可储存的最小值
WEOF wint_t类型的常量表达式,不与扩展字符集的任何成员对;相当于EOF的宽字符表示,用于指定宽字符输入的文件结尾

该库提供的输入/输出函数类似于stdio.h中的标准输入/输出函数。在标准I/O函数返回EOF的情况中,对应的宽字符函数返回WEOF。

宽字符I/O函数
函数原型
int fwprintf(FILE * restrict stream, const wchar_t * restrict format, ...);
int fwscanf(FILE * restrict stream, const wchar_t * restrict format, ...);
int swprintf(wchar_t * restrict s, size_t n, const wchar_t * restrict format, ...);
int swscanf(const wchar_t *restrict s, const wchar_t * restrict format, ...);
int vfwprintf(FILE *restrict stream, const wchar_t * restrict format, va_list arg);
int vfwscanf(FILE * restrict stream, const wchar_t * restrict format, va_list arg);
int vswprintf(wchar_t * restrict s, size_t n, const wchar_t * restrict format, va_list arg);
int vswscanf(const wchar_t * restrict s, const wchar_t * restrict format, va_list arg);
int vwprintf(const wchar_t * restrict format, va_list arg);
int vwscanf(const wchar_t * restrict format, va_list arg);
int wprintf(const wchar_t * restrict format, ...);
int wscanf(const wchar_t * restrict format, ...);
wint_t fgetwc(FILE *stream);
wchar_t *fgetws(wchar_t * restrict s, int n, FILE *restrict stream);
wint_t fputwc(wchar_t c, FILE *stream);
int fputws(const wchar_t * restrict s, FILE * restrict stream);
int fwide(FILE *stream, int mode);
wint_t getwc(FILE *stream);
wint_t getwchar(void);
wint_t putwc(wchar_t c, FILE *stream);
wint_t putwchar(wchar_t c);
wint_t ungetwc(wint_t c, FILE *stream);
有一个宽字符I/O函数没有对应的标准I/O函数:
int fwide(FILE *stream, int mode);
fwide()函数用于设置流的定向,根据mode的不同值来执行不同的工作。
如果mode为正,函数先尝试把形参表示的流指定为宽字符定向(wide-charaacter oriented);如果mode为负,函数先尝试把流指定了字节定向(byte oriented);如果mode为0,函数则不改变流的定向。该函数只有在流最初无定向时才改变其定向。在以上所有的情况中,如果流是宽字符定向,函数返回正值;如果流是字节定向,函数返回负值;如果流没有定向,函数则返回0。

wchar.h头文件参照string.h,也提供了一些转换和控制字符串的函数。一般而言,用wcs代替string.h中的str标识符,这样wcstod()就是strtod()函数的宽字符版本。

宽字符字符串工具
函数原型
double wcstod(const wchar_t * restrict nptr, wchar_t ** restrict endptr)
float wcstof(const wchar_t * restrict nptr, wchar_t ** restrict endptr)
long double wcstold(const wchar_t * restrict nptr, wchar_t ** restrict endptr)
long int wcstol(const wchar_t * restrict nptr, wchar_t ** restrict endptr, int base)
long long int wcstol(const wchar_t * restrict nptr, wchar_t ** restrict endptr, int base)
unsigned long int wcstoul(const wchar_t * restrict nptr, wchar_t ** restrict endptr, int base)
unsigned long long int wcstoull(const wchar_t * restrict nptr, wchar_t ** restrict endptr, int base)
wchar_t *wcscpy(wchar_t * restrict s1, const wchar_t *restrict s2)
wchar_t *wcsncpy(wchar_t * restrict s1, const wchar_t *restrict s2, size_t n)
wchar_t *wcscat(wchar_t * restrict s1, const wchar_t *restrict s2)
wchar_t *wcsncat(wchar_t * restrict s1, const wchar_t *restrict s2, size_t n)
int wcscmp(const wchar_t *s1, const wchar_t *s2)
int wcsncmp(const wchar_t *s1, const wchar_t *s2, size_t n)
int wcscoll(const wchar_t *s1, const wchar_t *s2)
size_t wcsxfrm(wchar_t * restrict s1, const wchar_t * restrict s2, size_t n)
wchar_t *wcschr(const wchar_t *s, wchar_t c)
size_t wcscspn(const wchar_t *s1, const wchar_t *s2)
size_t wcslen(const wchar_t *s)
wchar_t *wcspbrk(const wchar_t *s1, const wchar_t *s2)
wchar_t *wcsrchr(const wchar_t *s, wchar_t c)
size_t wcsspn(const wchar_t *s1, const wchar_t *s2)
wchar_t *wcsstr(const wchar_t *s1, const wchar_t *s2)
wchar_t *wcstok(wchar_t * restrict s1, const wchar_t * restrict s2, wchar_t **restrict ptr)
wchar_t *wmemchr(const wchar_t *s, wchar_t c, size_t n)
int wmemcmp(wchar_t * restrict s1, const wchar_t * restrict s2, size_t n)
wchar_t *wmemcpy(wchar_t * restrict s1, const wchar_t * restrict s2, size_t n)
wchar_t *wmemmove(wchar_t *s1, const wchar_t *s2, size_t n)
wchar_t *wmemset(wchar_t *s, wchar_t c, size_t n)
该头文件还参照time.h头文件中的strtime()函数,声明了一个时间函数:

size_t wcsftime(wchar_t * restrict s, size_t maxsize, const wchar_t * restrict format, const struct tm * restrict timeptr)

除此之外,该头文件还声明了一些用于宽字符字符串和多字节字符相互转换的函数:

宽字节和多字节字符转换函数
函数原型 函数原描述
wint_t btowc(int c) 如果在初始移位状态中c(unsigned char)是有效的单位字节字符,那么该函数返回宽字节表示;否则,返回WEOF
int wctob(wint_t c) 如果c是一个扩展字符集的成员,它在初始移位状态中的多字节字符表示的是单字节,该函数就返回一个转换为int类型的unsigned char的单字节表示;否则,函数返回EOF
int mbsinit(const mbstate_t *ps) 如果ps是空指针或指向一个指定为初始转换状态的数据对象,函数就返回非零值;否则,函数返回0
size_t mbrlen(const char * restrict s, size_t n, mbstate_t * restrict ps) mbrlen()函数相当于调用mbrtowc(NULL, s, n, ps != NULL ? ps : &internal),其中internal是mbrlen()函数的mbstate_t对象,除非ps指定的表达式只计算一次
size_t mbrtowc(wchar_t * restrict pwc, const char * restrict s, size_t n, mbstate_t * restrict ps) 如果s是空指针,调用该函数相当于把pwc设置为空指针、把n设置为1。如果s不是空指针,该函数最多检查n字节以确定下一个完整的多字节字符所需的字节数(包括所有的移位序列)。如果该函数确定了下一个多字节字符的结束处且合法,它就确定了对应宽字符的值。然后如果pwc不为空,则把值储存在pwc指向的对象中。如果检测到空的宽字符,函数返回0;如果检测到另一个有效宽字符,函数返回完整字符所需的字节数。如果n字节不足以表示一个有效的宽字符,但是能表示其中一部分,函数返回-2。如果出现编码错误,函数返回-1,并把EILSEQ储存在errno中,且不储存任何值
size_t wcrtomb(char * restrict s, wchar_t wc, mbstate_t * restrict ps) 如果s是空指针,那么调用该函数相当于把wc设置为空的宽字符,并为第1个参数使用内部缓冲区。如果s不是空指针,wcrtomb()函数则确定表示wc指定宽字符对应的多字节字符表示所需的字节数(包括所有移位序列),并把多字节字符表示储存在一个数组中(s指向该数组的第1个元素),最多储存MB_CUR_MAX字节。如果wc是空的宽字符,就在初始移位状态所需的移位序列后储存一个空字节。描述的结果状态就是初始转换状态。如果wc是有效的宽字符,该函数返回储存多字节字符所需的字节数(包括指定移位状态的字节)。如果wc无效,函数则把EILSEQ储存在errno中,并返回-1
size_t mbsrtowcs(wchar_t * restrict dst, const char **restrict src, size_t len, mbstate_t * restrict ps) mbstrtows()函数把src间接指向的数组中的多字节字符序列转换成对应的宽字符序列,从ps指向的对象所描述的转换状态开始,一直转换到结尾的空字符(包括该字符并储存)或转换了len个宽字符。如果dst不是空指针,则待转换的字符储存在dst指向的数组中。出现这两种情况时停止转换:如果字节序列无法构成一个有效的多字节字符,或者(如果dst不是空指针)len个宽字符已储存在dst指向的数组中。每转换一次都相当于调用一次mbrtowc()函数。如果dst不是空指针,就把空指针(如果因到达结尾的空字符而停止转换)或最后一个待转换多字节字符的地址赋给src指向的指针对象。如果由于到达结尾的空字符而停止转换,且dst不是空指针,那么描述的结果状态就是初始转换状态。如果执行成功,函数返回成功转换的多字节字符数(不包括空字符);否则函数返回-1
size_t wcsrtombs(char * restrict dst, const wchar_t ** restrict src, size_t len, mbstate_t * restrict ps) wcsrtombs()函数把src间接指向的数组中的宽字符序列转换成对应的多字节字符序列(从ps指向的对象描述的转换状态开始)。如果dst不是空指针,待转换的字符将被储存在dst指向的数组中。一直转换到结尾的空字符(包括该字符并储存)或换了len个多字节字符。出现这两种情况时停止转换:如果宽字符没有对应的有效多字节字符,或者(如果dst不是空指针)下一个多字节字符超过了储存在dst指向的数组中的总字节数len的限制。每转换一次都相当于调用一次wcrtomb()函数。如果dst不是空指针,就把空指针(如果因到达结尾的空字符而停止转换)或最后一个待转换多字节字符的地址赋给src指向的指针对象。如果由于到达结尾的空字符而停止转换,描述的结果状态就是初始转换状态。如果执行成功,函数返回成功转换的多字节字符数(不包括空字符);否则函数返回-1

标签: C语言

Powered by emlog  蜀ICP备18021003号   sitemap

川公网安备 51019002001593号