在Windows中,宽字符字符串使用的是UTF16编码,而多字节字符串使用的是GB2312编码,两者无法进行直接赋值。所以,在某些情况下需要对它们进行转换。本人大致用过以下几种转换方法。
- 使用Windows提供的WideCharToMultiByte系列函数进行转换
使用WideCharToMultiByte可以将宽字符转换成多字节,而使用MultiByteToWideChar可以将多字节转换成宽字符。使用这两个函数需要包含Windows.h这个头文件。代码例子如下:
* 宽字符转换成多字节int _tmain(int argc, _TCHAR* argv[])
{
WCHAR 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;
}
* 多字节转换成宽字符:
int _tmain(int argc, _TCHAR* argv[])
{
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;
}
- 使用wprintf系列函数进行转换
使用wprintfA函数可以很简单就将宽字符转换成多字节。代码例子如下:
int _tmain(int argc, _TCHAR* argv[])
{
WCHAR * wideChar = L"我是一个忧伤的字符串。";
char multiByte[MAX_PATH];
// 一个函数搞定
// 第一个参数是接收转换的结果
// 第二个参数设为 "%S" (注意S大写)
// 第三个参数是要转换的内容
wsprintfA(multiByte, "%S", wideChar);
cout << multiByte << endl;
system("pause");
return 0;
}
使用wprintfW函数可以很简单就将多字节转换成宽字符。代码例子如下:
int _tmain(int argc, _TCHAR* argv[])
{
setlocale(LC_ALL, "chs");
char * multiByte = "我是一个忧伤的字符串。";
WCHAR wideChar[MAX_PATH];
// 一个函数搞定
// 第一个参数是接收转换的结果
// 第二个参数设为 "%S" (注意S大写)
// 第三个参数是要转换的内容
wsprintfW(wideChar, L"%S", multiByte);
wcout << wideChar << endl;
system("pause");
return 0;
}
- 使用wcstombs系列函数进行转换
wcstombs可以实现从宽字符到多字节的转换,但是编译器会报警建议使用安全的wcstombs_s函数替代(此类报警可以通过#pragma warning(disable:4996)进行关闭)。代码例子如下:
int _tmain(int argc, _TCHAR* argv[])
{
setlocale(LC_ALL, "chs");
WCHAR * wideChar = L"我是一个很忧伤的字符串。";
char multiByte[MAX_PATH];
size_t numConverted = 0;
// 第一个参数为返回成功转换的字节数,如果不需要可以设为NULL
// 第二个参数为接收转换结果的缓冲区
// 第三个参数为要转换的内容
// 第四个参数为要转换的长度,单位是字节数
wcstombs_s(&numConverted, multiByte, wideChar, -1);
cout << "成功转换" << numConverted << "个字节:" << multiByte << endl;
system("pause");
return 0;
}
同样,相反过程的函数就是mbstowcs,对应的安全版本的函数为mbstowcs_s,代码例子如下:
int _tmain(int argc, _TCHAR* argv[])
{
setlocale(LC_ALL, "chs");
char * multiByte = "我是一个很忧伤的字符串。";
wchar_t wideChar[MAX_PATH];
size_t numConverted = 0;
// 第一个参数为返回成功转换的字节数,如果不需要可以设为NULL
// 第二个参数为接收转换结果的缓冲区
// 第三个参数为要转换的内容
// 第四个参数为要转换的长度,单位是WCHAR长度的个数
mbstowcs_s(&numConverted, wideChar, multiByte, -1);
wcout << L"成功转换" << numConverted << L"个字节:" << wideChar << endl;
system("pause");
return 0;
}
- 使用ATL的W2A和A2W宏进行转换
ATL的W2A和A2W宏用起来是最方便的,需要包含头文件atlconv.h。代码例子如下:
int _tmain(int argc, _TCHAR* argv[])
{
setlocale(LC_ALL, "chs");
char * multiByte = "我是忧伤的多字节字符串。";
wchar_t * wideChar = L"我是忧伤的宽字符字符串。";
// 在使用 W2A 和 A2W 宏之前需要加 USES_CONVERSION
USES_CONVERSION;
// W2A 完成宽字符到多字节的转换
cout << W2A(wideChar) << endl;
// A2W 完成多字节到宽字符的转换
wcout << A2W(multiByte) << endl;
system("pause");
return 0;
}