分类
未分类

多字节和宽字符之间的转换方法

在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;
}

 

“多字节和宽字符之间的转换方法”上的3条回复

发表评论

电子邮件地址不会被公开。 必填项已用*标注