晕!!!UTF8、ANSI不能互相转换吗

go16888888 2016-04-17 05:14:21
使用下面的函数,将字符串"卡(" 转成UTF-8,变成了"鍗?",然后再试着从UTF-8转ANSI就不行了变成了“?”,难道不能互转吗?

于是上网下了一堆的转换工具,发现都是这个问题,难道开发这些工具的兄弟都没注意到这个bug吗^_^

//使用:Convert(strA_in,strB_out,CP_UTF8,CP_ACP)//UTF8转换ANSI
// Convert(strA_out,strB_in,CP_ACP,CP_UTF8)//ANSI转换UTF8

void Convert(const char *strIn, char *strOut, int sourceCodepage, int targetCodepage)
{
int len=lstrlen(strIn);
int unicodeLen=MultiByteToWideChar(sourceCodepage,0,strIn,-1,NULL,0);
wchar_t* pUnicode;
pUnicode=new wchar_t[unicodeLen+1];
memset(pUnicode,0,(unicodeLen+1)*sizeof(wchar_t));
MultiByteToWideChar(sourceCodepage,0,strIn,-1,(LPWSTR)pUnicode,unicodeLen);
BYTE * pTargetData = NULL;
int targetLen=WideCharToMultiByte(targetCodepage,0,(LPWSTR)pUnicode,-1,/*(char *)pTargetData*/NULL,0,NULL,NULL);
pTargetData=new BYTE[targetLen+1];
memset(pTargetData,0,sizeof( char )*(targetLen+1));
WideCharToMultiByte(targetCodepage,0,(LPWSTR)pUnicode,-1,(char *)pTargetData,targetLen,NULL,NULL);
lstrcpy(strOut,(char*)pTargetData);
delete pUnicode;
delete pTargetData;
}
...全文
1727 11 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
zwfgdlc 2016-04-19
  • 打赏
  • 举报
回复
转换是没有问题的,主要是VS不能直接显示UTF-8编码的汉字,所以要写入记事本来检验是不是正常转换了

	char* szAnsi = "卡";
	char szUtf8[64] = { 0 };

	Convert(szAnsi, szUtf8);
	FILE* fp;
	fopen_s(&fp, "D:\\UTF8.TXT", "wb");
	fwrite("\xEF\xBB\xBF ", 3, 1, fp);
	fwrite(szUtf8, 4, 1, fp);
	fclose(fp);
赵4老师 2016-04-18
  • 打赏
  • 举报
回复
对电脑而言没有乱码,只有二进制字节;对人脑才有乱码。啊 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);
    }
}
  • 打赏
  • 举报
回复
转成UTF8是没问题的 问题是你还是把utf8编码的字符串用GBK来显示,自然就是错误的。
lm_whales 2016-04-18
  • 打赏
  • 举报
回复
UTF8 是UNICODE 的二次编码,不是UNICODE UTF8 可以视为 ANSI(ASCII) 只是还可以编码 UNICODE
go16888888 2016-04-18
  • 打赏
  • 举报
回复
LPTSTR CString::GetBuffer(int nMinBufLength) { ASSERT(nMinBufLength >= 0); if (GetData()->nRefs > 1 || nMinBufLength > GetData()->nAllocLength) { 。。。。。 GetBuffer参数必须>=0啊
lm_whales 2016-04-18
  • 打赏
  • 举报
回复
另外 GetBuffer(0) 是不对的,改为 -1 CString szTemp("卡("); CString szTemp1(""); Convert(szTemp1,szTemp.GetBuffer(-1),CP_ACP,CP_UTF8);//变成"鍗?" Convert(szTemp,szTemp1.GetBuffer(-1),CP_UTF8,CP_ACP);//变成"?". 正数和0 得到的是参数个字符 -1得到所有字符 GetBuffer 后,必须释放缓冲,不然可能有泄露
zwfgdlc 2016-04-18
  • 打赏
  • 举报
回复
utf-8编码是无法在VS里显示的,可以用UTF8编码写入记事本来查看

void Convert(const char *strIn, char *strOut, int sourceCodepage=CP_ACP, int targetCodepage=CP_UTF8)
{
	int len = lstrlenA(strIn);
	int unicodeLen = MultiByteToWideChar(sourceCodepage, 0, strIn, -1, NULL, 0);

	wchar_t* pUnicode;
	pUnicode = new wchar_t[unicodeLen + 1];
	memset(pUnicode, 0, (unicodeLen + 1)*sizeof(wchar_t));
	MultiByteToWideChar(sourceCodepage, 0, strIn, -1, (LPWSTR)pUnicode, unicodeLen);

	BYTE * pTargetData = NULL;
	int targetLen = WideCharToMultiByte(targetCodepage, 0, (LPWSTR)pUnicode, -1,/*(char *)pTargetData*/NULL, 0, NULL, NULL);
	pTargetData = new BYTE[targetLen + 1];
	memset(pTargetData, 0, sizeof(char)*(targetLen + 1));
	WideCharToMultiByte(targetCodepage, 0, (LPWSTR)pUnicode, -1, (char *)pTargetData, targetLen, NULL, NULL);

	//lstrcpy(strOut, (char*)pTargetData);
	lstrcpynA(strOut, (char*)pTargetData, targetLen+1);
	delete pUnicode;
	delete pTargetData;
}
zhouxiaofeng1021 2016-04-18
  • 打赏
  • 举报
回复
这不是bug吧
lm_whales 2016-04-18
  • 打赏
  • 举报
回复
ANSI(ASCII)不能表示汉字,如果有汉字,不宜转换为ANSI(ASCII)
go16888888 2016-04-17
  • 打赏
  • 举报
回复
CString szTemp("卡("); CString szTemp1(""); Convert(szTemp1,szTemp.GetBuffer(0),CP_ACP,CP_UTF8);//变成"鍗?" Convert(szTemp,szTemp1.GetBuffer(0),CP_UTF8,CP_ACP);//变成"?" 怎么能变正常啊
LubinLew 2016-04-17
  • 打赏
  • 举报
回复
ASCII码不能表示汉字,只能表示英文及英文符号, 正是因为ASCII只能表示256个字符。不能够表示中文所有字符, 所以才有的unicode, UTF8就是unicode的一种实现。

70,020

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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