acmilan作者
11年5个月前IP:四川
778779
3楼
Windows下的转码函数MultiByteToWideChar和WideCharToMultiByte,我们一般只用第1356四个参数,其它参数按照推荐值填写即可。其中第2个参数dwFlags、第7个参数lpDefaultChar,第8个lpUsedDefaultChar最好保持全0,因为有的代码页并不支持这三个参数,填写了会转码失败。第4个参数是输入字符串的大小,一般填-1,让系统判断它的大小。

MultiByteToWideChar的用法:
MultiByteToWideChar(代码页, 0, 输入字符串, -1, NULL, 0) // 返回所需缓冲区总大小(wchar_t的数量,包括末尾0)
MultiByteToWideChar(代码页, 0, 输入字符串, -1, 缓冲区, 缓冲区总大小) // 将char*转换为wchar_t*,若失败返回0

WideCharToMultiByte用法:
WideCharToMultiByte(代码页,  0, 输入字符串, -1, NULL, 0, NULL, NULL) // 返回所需缓冲区总大小(char的数量,包括末尾0)
WideCharToMultiByte(代码页,  0, 输入字符串, -1, 缓冲区, 缓冲区总大小, NULL, NULL) // 将wchar_t*转换为char*,若失败返回0

一个轻量级转码示例程序:
#include <windows.h>
#include <stdio.h>
#include <locale.h>
            
int from_codepage(UINT cp, LPCSTR str, LPWSTR wbuf, int num)
{
    return MultiByteToWideChar(cp, 0, str, -1, wbuf, num);
}
            
int to_codepage(UINT cp, LPCWSTR wstr, LPSTR buf, int num)
{
    return WideCharToMultiByte(cp, 0, wstr, -1, buf, num, NULL, NULL);
}
            
int main(int argc, char* argv[])
{
    setlocale(LC_ALL, ""); // 初始化C运行时使用本地编码
    wchar_t wstr[] = L"我是宽字符串";
    char str[] = "我是MBCS字符串";
            
    UINT codepage = GetACP(); // 获取程序当前的ANSI字符集
    if (codepage == 936 && IsValidCodePage(54936)) // 如果为GB2312且GB18030有效
        codepage = 54936; // 替换为GB18030
    printf("使用代码页:%d\n", codepage);
            
    // 转码成宽字符串
    int wcount = from_codepage(codepage, str, NULL, 0); // 获取所需缓冲区大小(包括结束0)
    wchar_t *wbuf = new wchar_t[wcount];
    from_codepage(codepage, str, wbuf, wcount); // 正式转码
    printf("%ls\n", wbuf);
            
    // 转码成MBCS字符串
    int count = to_codepage(codepage, wstr, NULL, 0); // 获取所需缓冲区大小(包括结束0)
    char *buf = new char[count];
    to_codepage(codepage, wstr, buf, count); // 正式转码
    printf("%s\n", buf);
            
    delete[] buf;
    delete[] wbuf;
    return 0;
}</locale.h></stdio.h></windows.h>
评论
文号 / 778779

千古风流
名片发私信
学术分 4
总主题 466 帖总回复 2942 楼拥有证书:进士 学者 笔友
注册于 2009/05/30 21:22:42最后登录 2019/01/31 17:16:38
主体类型:个人
所属领域:无
认证方式:邮箱
IP归属地:0

个人简介

暂未填写
笔记
{{note.content}}
{{n.user.username}}
{{fromNow(n.toc)}} {{n.status === noteStatus.disabled ? "已屏蔽" : ""}} {{n.status === noteStatus.unknown ? "正在审核" : ""}} {{n.status === noteStatus.deleted ? '已删除' : ''}}
  • 编辑
  • 删除
  • {{n.status === 'disabled' ? "解除屏蔽" : "屏蔽" }}
我也是有底线的