请教高人:关于字符串编码的问题

吉哥 2014-10-29 10:12:32
别人提供的一个控件接口返回字符串,如,“ABC中国”。如果设置SetThreadLocale(1033),返回结果“A0B0?0?0?0?0”;如果设置SetThreadLocale(2052),返回结果“A0B0????”。请问,内部怎么编码的,导致输出的结果怎么不一样?如果当前系统环境是1033,用MultiByteToWideChar好像也不对。
...全文
259 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
向立天 2014-12-10
  • 打赏
  • 举报
回复
您好 我是本版版主 此帖已多日无人关注 请您及时结帖 如您认为问题没有解决可按无满意结帖处理 另外本版设置了疑难问题汇总帖 并已在版面置顶 相关规定其帖子中有说明 您可以根据规定提交您帖子的链接 如您目前不想结帖只需回帖说明 我们会删除此结帖通知 见此回复三日内无回应 我们将强制结帖 相关规定详见界面界面版关于版主结帖工作的具体办法
笨笨仔 2014-11-10
  • 打赏
  • 举报
回复
利用API做的转换函数,供参考:

// ANSI To UNCODE转换
CString CStringProc::AnsiToUnicode(char * szAnsi)
{
	CString str;
	// ansi to unicode
	//预转换,得到所需空间的大小
	int wcsLen;
	wcsLen= ::MultiByteToWideChar(CP_ACP, NULL, szAnsi, strlen(szAnsi), NULL, 0);
	//分配空间要给'\0'留个空间,MultiByteToWideChar不会给'\0'空间
	wchar_t* wszString = new wchar_t[wcsLen + 1];
	//转换
	::MultiByteToWideChar(CP_ACP, NULL, szAnsi, strlen(szAnsi), wszString, wcsLen);
	//最后加上'\0'
	wszString[wcsLen] = '\0';			// UNICODE字串
	str=wszString;
	delete wszString;
	return str;
}
吉哥 2014-11-10
  • 打赏
  • 举报
回复
引用 7 楼 wxhxj0268 的回复:
你如何接收返回数据的? 返回到缓冲区?还是返回到字串?还是……? 这明显就是个字符集标准的转换问题。
控件中有接口,返回字符串——也可以说是缓冲区,通过内存地址读取看到以上结果。
Saleayas 2014-10-31
  • 打赏
  • 举报
回复
MultiByteToWideChar 设置好第一个参数,比如 GB码就是 936.
笨笨仔 2014-10-31
  • 打赏
  • 举报
回复
你如何接收返回数据的? 返回到缓冲区?还是返回到字串?还是……? 这明显就是个字符集标准的转换问题。
吉哥 2014-10-31
  • 打赏
  • 举报
回复
在线,等待中。望高人指点?
吉哥 2014-10-30
  • 打赏
  • 举报
回复
如上所言,两个汉字最多六个字节,而不会是8个字节。用VC的内存窗口查看,确实是正确的是A0B0????——SetThreadLocale(2052)后;原来GetThreadLocale得到的是1033(英文)就不对,是A0B0?0?0?0?0。现在问题已经解决,因为设计封装好的控件,所以搞不清原因。目前是这样解决的,通过控件接口获得字符串后,调用WideCharToMulityByte(参数一定要用THREAD_CAP),然后再调用MulityByteToWideChar(参数一定要是_CAP),就得到想要的Unicode字符串了。不明白什么原因,望指正。
吉哥 2014-10-29
  • 打赏
  • 举报
回复
关键是,现在返回的结果是“A0B0?0?0?0?0”。注意,它把两个汉字做成8个字节了。是控件BUG,还是一种别的编码?这方面,我也不太懂。
吉哥 2014-10-29
  • 打赏
  • 举报
回复
引用 1 楼 oyljerry 的回复:
用unicode编码字符串再显示
你好,你说的具体点吗?
oyljerry 2014-10-29
  • 打赏
  • 举报
回复
用unicode编码字符串再显示
赵4老师 2014-10-29
  • 打赏
  • 举报
回复
对电脑而言没有乱码,只有二进制字节;对人脑才有乱码。啊 GBK:0xB0 0xA1,Unicode-16 LE:0x4A 0x55,Unicode-16 BE:0x55 0x4A,UTF-8:0xE5 0x95 0x8A 用以下函数显示数据的原始字节
void HexDump(char *buf,int len,int addr) {
    int i,j,k;
    char binstr[80];

    for (i=0;i<len;i++) {
        if (0==(i%16)) {
            sprintf(binstr,"%08x -",i+addr);
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
        } else if (15==(i%16)) {
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
            sprintf(binstr,"%s  ",binstr);
            for (j=i-15;j<=i;j++) {
                sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
            }
            printf("%s\n",binstr);
        } else {
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
        }
    }
    if (0!=(i%16)) {
        k=16-(i%16);
        for (j=0;j<k;j++) {
            sprintf(binstr,"%s   ",binstr);
        }
        sprintf(binstr,"%s  ",binstr);
        k=16-k;
        for (j=i-k;j<i;j++) {
            sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
        }
        printf("%s\n",binstr);
    }
}

15,979

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧