彻底弄懂UTF-8、Unicode、宽字符、locale( 三 )
mbstowcs()将多字节字符串转换为宽字符串 。
wcstombs()将宽字符串转换为多字节字符串 。
考虑下面的例子:
#include <locale.h>#include <stdio.h>#include <time.h>#include <stdlib.h>#include <wchar.h>#include <string.h>wchar_t* str2wstr(const char const* s) { const size_t buffer_size = strlen(s) + 1; wchar_t* dst_wstr = (wchar_t *)malloc(buffer_size * sizeof (wchar_t)); wmemset(dst_wstr, 0, buffer_size); mbstowcs(dst_wstr, s, buffer_size);return dst_wstr;}void printBytes(const unsigned char const* s, int len) { for (int i = 0; i < len; i++) { printf("0x%02x ", *(s + i)); } printf("");}int main () { char s[10] = "你好"; //内存中对应0xe4 0xbd 0xa0 0xe5 0xa5 0xbd 0x00wchar_t ws[10] = L"你好"; //内存中对应0x60 0x4f 0x00 0x00 0x7d 0x59 0x00 0x00 0x00 0x00 0x00 0x00printf("Locale is: %s", setlocale(LC_ALL, "zh_CN.UTF-8")); //Locale is: zh_CN.UTF-8 printBytes(s, 7); //0xe4 0xbd 0xa0 0xe5 0xa5 0xbd 0x00printBytes((char *)ws, 12); //0x60 0x4f 0x00 0x00 0x7d 0x59 0x00 0x00 0x00 0x00 0x00 0x00printBytes((char *)str2wstr(s), 12); //0x60 0x4f 0x00 0x00 0x7d 0x59 0x00 0x00 0x00 0x00 0x00 0x00return(0);}编译后,执行结果如下:
Locale is: zh_CN.UTF-80xe4 0xbd 0xa0 0xe5 0xa5 0xbd 0x00 0x60 0x4f 0x00 0x00 0x7d 0x59 0x00 0x00 0x00 0x00 0x00 0x00 0x60 0x4f 0x00 0x00 0x7d 0x59 0x00 0x00 0x00 0x00 0x00 0x00 第二行输出也印证了我们之前说的多字节字符串在内存中以UTF-8存储,"0xe4 0xbd 0xa0 0xe5 0xa5 0xbd"正是"你好"的UTF-8编码 。
第三行输出印证了之前说的宽字符串在内存中以Unicode存储,"0x60 0x4f 0x00 0x00 0x7d 0x59 0x00 0x00"正好是宽字符串L"你好"对应的Unicode 。
setlocale(LC_ALL, "zh_CN.UTF-8")设置locale,程序将以UTF-8解码宽字符串 。调用mbstowcs()后,可以看到“你好”的UTF-8编码 "0xe4 0xbd 0xa0 0xe5 0xa5 0xbd 0x00"确实被转换成了“你好”对应的Unicode "0x60 0x4f 0x00 0x00 0x7d 0x59 0x00 0x00 0x00 0x00 0x00 0x00" 。
如果将setlocale(LC_ALL, "zh_CN.UTF-8")换成setlocale(LC_ALL, "en_US.iso88591 ");那么最后一行的输出也就会不一样 。
【彻底弄懂UTF-8、Unicode、宽字符、locale】
推荐阅读
- Java源码中>>,>>>的区别是啥?我给你彻底讲清
- 一篇文章彻底搞懂base64编码原理
- 吕秀才喻恩泰彻底翻车 喻恩泰八卦
- 一分钟弄懂什么是分布式和微服务
- 仅需 5 分钟,彻底理解 cookie、session、token
- 汽车上常见的几种悬挂,你分清了吗?三分钟教你弄懂
- 这样瘦肚子最快每天10分钟彻底摆脱小肚腩,做个人人羡慕的美腹婆
- 彻底理解cookie,session,token
- 家里有蟑螂怎么能彻底消灭 卧室有蟑螂怎么办
- 记住:永远不要在 MySQL 中使用 UTF-8