- 一、windows
- 二、linux
- 三、c语言
- 四、汉字“我”的宽字符码和多字节码是多少
- 1、宽字符和多字节字符的本质
- 2、汉字我的宽字符码和多字节码分别是多少
- 3、demo
- 宽字符转换成多字节
#include#include using namespace std; int main() { wchar_t wideChar[] = L"我是一个宽字符"; // 1. 首先指定接收转换结果的指针 char * multiByte; // 2. 然后第一次调用函数,获取存储转换结果所需缓冲区的大小 int len = WideCharToMultiByte(CP_ACP, NULL, wideChar, // 要被转换的宽字符字符串 -1, // 要转换的长度,设为-1表示转换整串 NULL, // 第一次调用,接收缓冲区设置为NULL NULL, // 接收缓冲区的大小,设为NULL表示让函数返回需要的大小 NULL, NULL); // 3. 根据返回的结果创建合适大小的缓冲区 multiByte = new char[len]; // 4. 第二次调用函数,进行真正的转换 WideCharToMultiByte(CP_ACP, NULL, wideChar, // 要被转换的宽字符字符串 -1, // 要转换的长度,设为-1表示转换整串 multiByte, // 第二次调用,设为接收转换结果的缓冲区指针 len, // 设定接收缓冲区大小 NULL, NULL); // 5. 转换结束,可以输出查看转换结果 cout << multiByte << endl; delete multiByte; system("pause"); return 0; }
输出
我是一个宽字符
请按任意键继续. . .
- 多字节转换成宽字符:
#include#include using namespace std; int main() { setlocale(LC_ALL, "chs"); char multiByte[] = "我是一个多字节字符串。"; // 1. 首先指定接收转换结果的指针 WCHAR * wideChar; // 2. 然后第一次调用函数,获取存储转换结果所需缓冲区的大小 int len = MultiByteToWideChar(CP_ACP, NULL, multiByte, // 要被转换的多字节字符串 -1, // 要转换的长度,设为-1表示转换整串 NULL, // 第一次调用,接收缓冲区设为NULL 0); // 接收缓冲区长度,设为0代表函数返回需要的长度 // 3. 根据返回的结果创建合适大小的缓冲区 wideChar = new WCHAR[len]; // 4. 第二次调用函数,进行真正的转换 MultiByteToWideChar(CP_ACP, NULL, multiByte, // 要被转换的多字节字符串 -1, // 要转换的长度,设为-1表示转换整串 wideChar, // 第二次调用,设为接收转换结果的缓冲区 len); // 设置接收缓冲区的大小 // 5. 转换结束,可以输出查看转换结果 wcout << wideChar << endl; delete wideChar; system("pause"); return 0; }
输出
我是一个多字节字符串。
参见:多字节和宽字符之间的转换方法
二、linux- iconv.h
- linux下的原型函数
- 不单单可以做宽字符和多字节字符的转换,还可以用做不同字符编码的转换。
这个用的不多,而且c++20提供了相应的函数转换,在此不做过多研究,后面会整理一篇c++ 20提供的字符转换函数。
参见:linux 宽字符与多字节字符之间的转换
三、c语言-
c语言提供了wcstombs、mbstowcs(不安全)
-
(因为不安全,在vs2017中已经编译不过了,让用更加安全的wcstombs_s、mbstowcs_s,想要编译通过,可以在visual中:项目右键 – 属性 – C/C++ – 预处理器 – 预处理器定义,在里面添加 _CRT_SECURE_NO_DEPRECATE 即可)
-
windows和linux都可以使用;
-
存在《四、wchar_t》中备注说的问题待验证。
-
wcstombs_s、mbstowcs_s是微软提供的,linux下肯定是无法使用的。
- wcstombs
size_t wcstombs (char* dest, const wchar_t* src, size_t max);
Convert wide-character string to multibyte string
#include#include #include #define BUFFER_SIZE 50 int main() { setlocale(LC_ALL, "chs"); size_t ret; char mb[50]; wchar_t wc[] = L"我是一个宽字符"; //wchar_t* wcStr = wc; ret = wcstombs(mb, wc, BUFFER_SIZE); printf("要转换的字符数 = %un", ret); printf("多字节字符 = %snn", mb); return(0); }
输出
要转换的字符数 = 14
多字节字符 = 我是一个宽字符
- mbstowcs
size_t mbstowcs (wchar_t* dest, const char* src, size_t max);
Convert multibyte string to wide-character string
#include#include #include #define BUFFER_SIZE 50 int main() { setlocale(LC_ALL, "chs"); char mbyte[50]; wchar_t * wbyte =NULL; strcpy(mbyte, "我是一个多字节字符"); size_t mlen = strlen(mbyte); int dSize = mbstowcs(wbyte, mbyte, 0) + 1; wbyte = new wchar_t[dSize]; wmemset(wbyte, 0, dSize); int len = mbstowcs(wbyte, mbyte, mlen);//mlen长度比所需要的长,不会失败。 return(0); }
参见:
1、wcstombs
2、mbstowcs()/wcstombs()
由于我们设置成了setlocale(LC_ALL, “chs”);所以字符集是gbk。
- 多字节字符就是gbk字符
- 宽字节字符是Unicode字符
- 备注:我们知道gbk是多字节字符,至于为何转换成宽字符变成了Unicode编码,可能是默认的吧。
- gbk:GBK 编码
- 汉字“我”:CED2是十六进制。对应的十进制就是52946.
- Unicode: https://unicode-table.com/cn/
- 汉字“我”:6211是十六进制。对应的十进制就是25105.
#include#include #include #define BUFFER_SIZE 50 using namespace std; int main() { setlocale(LC_ALL, "chs"); char mbyte[50]; wchar_t * wbyte =NULL; strcpy(mbyte, "我"); size_t mlen = strlen(mbyte); int dSize = mbstowcs(wbyte, mbyte, 0) + 1; wbyte = new wchar_t[dSize]; wmemset(wbyte, 0, dSize); int len = mbstowcs(wbyte, mbyte, mlen); cout << &mbyte<
- 输出
00F3F984
00F3F978
我
我
备注:00F3F978为指针地址,应该查看指针指向的地址。如下图所示值为0x013107E8
- 查看汉字“我”的gbk编码值为CED2(十六进制)、Unicode的编码值6211(十六进制)



