关于宽窄字符的这个东西,虽然用到不多,但是碰到的时候还是理清楚一点的话,自己说的很难清除,所以基本就都借鉴别人的文章来说明了。
char这个很熟了,都是固定的8bit,一字节。只能表示ASII码表中的256个字符,包括前128个可见字符和后面的128个不可见字符。
而wchar_t则是因为char所能表示的字符数太少(256个)而应运而生的,它的长度可以8bit,16bit,32bit,长度是与不同平台上的c库相关的。其实这个长度是根据指定平台上想要用的encoding编码方式来设定的。给 wchar_t 类型的字符或字符数组(也就是字符串)赋值要冠以 L;格式化输出(如 printf) wchar_t 类型的字符串, 要用 %S(而非 %s)。(我更多的是看到用ls输出);而且 要注意一点,printf和wprintf不能混用,否则不会打印。
wchar_t就是存储的字符的unicode码值的编码值,如windows下就是unicode码值的utf-16编码值。下面一个例子:
wchar_t w1= L'中'; //Unicode 编码
wchar_t w2= '中'; //Ansi编码
printf( "%0x %0x ",w1,w2);
结果:
4e2d d6d0
虽然同样是赋值给wchar_t,但是不同的编码则值是不同的。同时也说明了wchar_t不光是可以存储Unicode宽字符,也可以存储其它的编码。
wchar_t c= L'中';
wcout.imbue(locale("chs"));
wcout<<c<<endl;
上述代码能正常输出'中'字
wchar_t c= '中';
wcout.imbue(locale("chs"));
wcout<<c<<endl;
上述代码不能正常输出'中'字,结果是什么也没输出。
所以如果是需要宽字符参数的API里传入值为Ansi编码值的wchar_t可能会得到不可预测的结果。
c/c++标准只是声明wchar_t是一个可以表示字符集中的任意一个字符的足够宽的变量类型。wchar_t可以用任何encoding编码方式来存储这个字符,如ANSI, or UCS-2, or UCS- 4, 甚至是SCU-128,只不过我们通常是用unicode编码方式。wchar_t是与实现相关的。
所以为了可移植性,我们不能假定wchar_t的编码方式,然后根据编码方式做一些相关性操作,我们只能理解它为一个足够宽的字符类型。
上面的ansi,指windows平台的一种ascii扩展码,他将ascii码扩展到8bits,增加了0x80-0xff共128个字符。
对于ANSI码表而言,它兼容ASCII码表,0x00~0x7F之间的字符,依旧是1个字节代表1个字符。为使计算机支持更多语言,通常使用 0x80~0xFF 范围的 2 个字节来表示 1 个非英语字符。像GB2312, BIG5, JIS 等使用ANSI码表的0x80~0xFF范围的 2 个字节来代表一个字符的各种汉字延伸编码方式,统称为ANSI 编码。比如:汉字 '中' 在GB2312码表中,使用 [0xD6,0xD0] 这两个字节存储。ANSI 编码与UTF-8一样,也是一种编码方式。
ANSI,是通过两个窄字符char来表示一个汉字的。同一个ANSI编码值,对于不同的system locale值(不同的字符集),显示出来的字符是不一样的。默认情况下,如果不加_T或L,默认情况下所有的字符都是ANSI编码。
然后暂时就说到这里,下面说一下转化的东西,先说一下两个词:
mbs: multi byte string, 用char作为存储类型, 一个字符可能对应1个或者多个char, 不能直接确定字符边界. charset不确定. 过去的程序都是采用mbs的.
wcs: wide character string, 用wchar_t作为存储类型, 一个字符对于一个wchar_t. 使用unicode编码, charset与OS相关, 在windows平台中为UTF16(UCS-2), 在大多数unix平台中为UTF32(UCS-4).
而用于转化的,一般也就是mbstowcs,wcstombs,WideCharToMultiByte,MultiByteToWideChar这四个函数,从功能上讲,基本相同。但WideCharToMultiByte()和MultiByteToWideChar()用于wince5.0以上。是win api.自适用中文。mbstowcs()函数和wcstombs()函数,选自CRT库。平台无关,但需设定locale。就是需要正确的字符集啦,这里上面都说的啦。比如:setlocale(LC_ALL, "C"),只是以ansi页来解释,而setlocale(LC_ALL, "chs")是以gbk页码来翻译为中文的双字节。
MultiByteToWideChar等则是根据接口中指定的encoding方式转换。
这里就完了,然后有个文章可以看一下:http://club.topsage.com/thread-2227977-1-1.html
另外其他的参考的文章:http://blog.csdn.net/nodeathphoenix/article/details/7416725
http://www.cnblogs.com/MichaelOwen/articles/2128771.html
http://blog.csdn.net/code_pipeline/article/details/1863665