首页 > 其他分享 >std::string std::wstring char w_char 内部中文编码

std::string std::wstring char w_char 内部中文编码

时间:2023-02-09 19:55:49浏览次数:59  
标签:std 编码 nByte zname wstring char string

最近在处理一个字符串转码问题,故记录一下过程

该需求是外部 sdk 的一个 api 需要一个 char* 字符串路径入参,我以往是将宽字符串转为 UTF8 后再传给 sdk

这次这个 api 似乎不接受 UTF8 编码的字符串路径,于是我改用系统编码传参作测试,也就是将 GB2312 编码的字符串路径传给它

结果显示该 api 只接受本地编码的字符串路径,因此我要处理宽字符串转为系统编码的问题

我在 stackoverflow 论坛上搜到一些答案

其中有一个方法要注意避坑,

这是个高赞答案,链接:https://stackoverflow.com/a/12097772/11128312

但是这个只适用于英文字符,因为这种转换相当于把宽字节的第二个字节抹除了,比如,

“帮助” 的 unicode 编码为:2e 5e a9 52

使用上图的方法就给你干掉宽字节的第二个字节,

变成:2e a9

这是一个四不像字符

英文字符就不一样了,比如

“he” 的 unicode 编码为:68 00 65 00

用 std::string 就可以去掉 00,

变成:68 65

故我们要用其他方法来转换,方法很多,我这里列举两个,

C++17 后支持 std::filesystem::path 直接转,示例,

#include <filesystem>

const std::wstring wPath = GetPath(); // some function that returns wstring
const std::string path = std::filesystem::path(wPath).string();

也可以使用 WcToMb 工具函数

WcToMb 原型:

char* WcToMb(const wchar_t *str)
{
    char *mbstr = NULL;
    lo_W2C(&mbstr, str);
    return mbstr;
}

lo_W2C 内部也是用的 WideCharToMultiByte 函数转换的

lo_W2C 函数原型

    /*
    ** Convert microsoft unicode to multibyte character string, based on the
    ** user's Ansi codepage.
    **
    ** Space to hold the returned string is obtained from
    ** malloc().
    */
    int lo_W2C(char** pout ,const wchar_t *zWide)
    {
#if (defined(WIN32) || defined(_WIN32) )
        char *zname = 0;
        int  codepage = 0;
        int  nByte = 0;

        if( !zWide || *zWide == '\0' )
            return 0;

#if defined(_WIN32_WCE)
        codepage =  CP_ACP ;
#else
        codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
#endif
        nByte = WideCharToMultiByte(codepage, 0, zWide, -1, 0, 0, 0, 0);
        zname = (char*)malloc( nByte + 1 );
        if( zname == 0 ) return 0;

        nByte = WideCharToMultiByte(codepage, 0, zWide, -1, zname, nByte+1, 0, 0);
        if( nByte > 0 )    zname[nByte] = '\0';

        *pout = zname;
        return nByte;
#else

        const wchar_t* in  = zWide;
        size_t in_len = wcslen(in);
        size_t outlen = bbiconv_counts_wchar_2_gbk(in , in_len);
        if( outlen <= 0 )
            return -1;

        char* out_ptr = (char*)malloc( (sizeof(char)) * (outlen+1) );
        if( !out_ptr )
            return -1;

        bbiconv_wchar_2_gbk(in , in_len , out_ptr , outlen);
        *pout = out_ptr;
        return outlen;

#endif //#if (defined(WIN32) || defined(_WIN32) )

    }

补充:

std::wstring 和 wchar_t 内部中文编码是按照 unicode 编码的
std::string 和 char 内部中文编码是按照系统字符集编码,一般中文是 GB2312 字符集

另附:

 

标签:std,编码,nByte,zname,wstring,char,string
From: https://www.cnblogs.com/strive-sun/p/17106836.html

相关文章