碰到的一个编码问题

今天看到一个utf-8,utf-16,utf-32之间转换的程序ConvertUTF,于是拿来玩玩,于是就有了这篇文章。
照搬cocos2d里面的ConvertUTF到我的项目。

   /**
    *    std::u16string utf16;
    *    bool ret = StringUtils::UTF8ToUTF16("你好hello", utf16);
    *    if (ret) {
    *        do_some_thing_with_utf16(utf16);
    *    }
    */
    CC_DLL bool UTF8ToUTF16(const std::string& utf8, std::u16string& outUtf16);

仿照的例子的写法,我写了个测试程序:

void testUtf()
{
    std::string str = "你好";
    std::u16string util16String;
    bool ret = StringUtil::UTF8ToUTF16(str,util16String);
    if (ret)
    {
        printf("success");
    }
    else{
        printf("fail");
    }
}
结果:fail

于是百思不得其解,在cocos2d中搜索UTF8ToUTF16的引用。在Label中发现就有引用。

void Label::setString(const std::string& text)
{
    if (text.compare(_originalUTF8String))
    {
        _originalUTF8String = text;
        _contentDirty = true;

        std::u16string utf16String;
        if (StringUtils::UTF8ToUTF16(_originalUTF8String, utf16String))
        {
            _currentUTF16String  = utf16String;
        }
    }
}

而且Label对文本的各种设置都是根据_currentUTF16String 来的,所以UTF8ToUTF16不应该失败呀。
经过调试代码发现:text并不为”你好”(我加了个Label,设置显示文本为”你好”)。而是:”浣犲ソ”。
于是想到也许编码有问题,然后复习了下各种编码 utf-8,utf-16,utf-32,gbk,gb2312,ansi等等。
在EditText查看各种编码之间切换”你好”,发现”浣犲ソ”是utf-8的你好转用ansi,gbk,gb2312来解码的字符。所以以上的text就是通过不正确的解码utf-8的你好 得来的。继续往上追寻。

int lua_cocos2dx_Label_setString(lua_State* tolua_S)
{
//...
        std::string arg0;

        ok &= luaval_to_std_string(tolua_S, 2,&arg0, "cc.Label:setString");
        if(!ok)
        {
            tolua_error(tolua_S,"invalid arguments in function 'lua_cocos2dx_Label_setString'", nullptr);
            return 0;
        }
        cobj->setString(arg0);
//...

    return 0;
}

static inline const char* tolua_tocppstring (lua_State* L, int narg, const char* def) {

    const char* s = tolua_tostring(L, narg, def);
    return s?s:"";
};

TOLUA_API const char* tolua_tostring (lua_State* L, int narg, const char* def)
{
    return lua_gettop(L)<abs(narg) ? def : lua_tostring(L,narg);
}

现在来到了lua层面,难道lua层面做了什么操作,仿佛继续不下去了。那就先暂时搁一边吧。我思考了几个问题:
1:什么时候发生了解码操作?
2:我输入的“你好”到底是什么编码?
带着这两个问题,我继续探索下去了,还是上面我的那个测试程序。
输入的“你好”应该和编辑器的当前编码有关,所以查看了下visual studio的编码方式:发现是gb2312编码,我改成了utf-8。然后跑一下测试程序惊奇的发现std::string str = “你好”;之后str就是”浣犲ソ”了,所以明显std::string读取“你好”的时候就发生了解码,网上搜索了一番发现VC++默认std::string以ansi读取,clang是unicode方式读取,关键是结果:success。其实很好理解,之前的编码是gb2312,并不是utf-8,所以 转换的输入都错了,怎么能得到正确的u16string呢。
现在我们明确了一点:传入的必须是utf-8编码的字符串。那么写lua的时候是什么编码呢,于是查看Cocos Code IDE,默认为GBK编码,怎么不是utf-8?于是更改ide的编码方式,发现无论如何更改,文件中的“你好”都不会发生变化,按理来说应该会乱码呀!因为对这个垃圾开发工具印象一直不是很好,所以我就认为这个开发工具有问题吧,其实我用EditText打开它而且无论我怎么更改编码方式,都是告诉我它是以utf-8编码的。
现在一切都明朗了。输入的字符必须为utf-8。
我的visual studio默认为gb2312,难道我在C++代码中设置Label的文本为“你好”会是乱码么?我联想到了一开始接触cocos2dx,并没有用lua,当时设置中文就是乱码,现在一直没有碰到问题(现在用lua),还以为是版本更新了,对它做了优化。于是我又尝试了,在C++代码中添加了“你好”Label,果然发现是乱码,因为我们已经知道 为什么是乱码,于是我把“你好”改成“浣犲ソ”,哈哈,果然显示出了 “你好”,“浣犲ソ”就是utf-8的“你好”,转化的也是utf-8,转换的时候并不管你现在是什么编码,它的内存是以utf-8编码存在的就好了,这个并不会跟着你的解码方式改变而改变。

Ending….

  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值