首先引用两篇非常好的博文,什么时候对字符集编码概念不清楚的时候,一定要看看。
另外引用一个列举的宽字符处理函数比较全的文章,文章中没提到的是文件打开函数_wopen(...),格式化输出函数wprintf(...)。
宽字符处理函数函数与普通函数对照表
然后是两段我做的小例子,都可以输出汉字:
使用宽字符(Unicode编码,vc下为UTF-16,所有字符都是16位,其中ASCII字符高字节0x00):
#include "stdio.h" #include "stdlib.h" #include <locale.h> int main(void) { wchar_t arr[50]=L"零一二三四五六七八九1234"; int size=wcslen(arr); printf("length of arr:%d\n",size); setlocale(LC_ALL,"chs"); wprintf(L"%s",arr); getchar(); return 0; }
观察arr的内存如下:
解释:
普通字符串,又叫多字符字符串(MultiByteString)对应ANSI编码,在简体中文系统下就是GB2313;
宽字符字符串(WideCharacterString)对应Unicode编码,在vc下就是UTF-16。
在双引号之间的字符串字面值是普通字符串,加上L的标识就转化成宽字符字符串存储在arr里。wcslen是读取宽字符字符串含有的字符数,不能用strlen因为该函数以一个'\0'作为字符结束的标志,上图中可以看出“二”这个汉字的低字节为0x00,如果用strlen肯定输出2,而不是想要得到的14。输出宽字符字符串需要使用wprintf(...),但是在使用之前需要设置当前语言环境locale(我猜测英文取自local environment),因为c++ runtime缺省的locale是POSIX locale,不能处理汉字,所以需要设置成"chs"表明当前语言环境是中文GB2313编码,之后wprintf就知道要把Unicode编码的宽字符字符串转化成GB2313编码的普通字符串输出了。
使用普通字符(ANSI编码,简体中文系统下是GB2313,使用 0x80~0xFF 范围的 2 个字节来表示 1 个汉字字符,使用0x00~0x7f范围的1个字节表示1个ASCII字符):
#include "stdio.h" #include "stdlib.h" #include <locale.h> int main(void) { char arr[50]="零一二三四五六七八九1234"; int size=strlen(arr); printf("length of arr:%d\n",size); printf("%s",arr); getchar(); return 0; }
观察arr的内存如下:
解释:
arr里直接存的是ANSI编码的字符串,然后printf也支持ANSI输出,所以直接就可以输出汉字了。