GB2312转UTF8,转换时汉字是双数没问题,单数最后一个字符乱码

ATMCash4423 2015-10-23 11:38:58


void ConvertGB2312ToUtf8_t(CString& strInfo)
{
int len=MultiByteToWideChar(CP_ACP, 0, (LPCTSTR)strInfo, -1, NULL,0);
unsigned short * wszUtf8 = new unsigned short[len+1];
memset(wszUtf8, 0, len * 2 + 2);
MultiByteToWideChar(CP_ACP, 0, (LPCTSTR)strInfo, -1, (LPWSTR)wszUtf8, len);

len = WideCharToMultiByte(CP_UTF8, 0, (LPWSTR)wszUtf8, -1, NULL, 0, NULL, NULL);
char *szUtf8=new char[len + 2];
memset(szUtf8, 0, len + 2);
len = WideCharToMultiByte (CP_UTF8, 0, (LPWSTR)wszUtf8, -1, szUtf8, len, NULL,NULL);

strInfo = szUtf8;
delete[] szUtf8;
delete[] wszUtf8;
}


单数:
CString dre = "http://192.168.0.84:8080/publish/taskfile/SMS20151023104800001/多手段测试.zip";
ConvertGB2312ToUtf8_t(dre);
dre 输出结果:
http://192.168.0.84:8080/publish/taskfile/SMS20151023104800001/澶氭墜娈垫祴璇?zip

双数:
CString dre = "http://192.168.0.84:8080/publish/taskfile/SMS20151023104800001/多手段测试试.zip";
ConvertGB2312ToUtf8_t(dre);
dre 输出结果:
http://192.168.0.84:8080/publish/taskfile/SMS20151023104800001/澶氭墜娈垫祴璇曡瘯.zip
...全文
737 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2015-10-30
  • 打赏
  • 举报
回复
对电脑而言没有乱码,只有二进制字节;对人脑才有乱码。啊 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);
    }
}
李元静 2015-10-29
  • 打赏
  • 举报
回复
汉字在GBK编码中占2个字节,在UTF—8中占3个字节。而java中string默认采用us2默认汉字只有一个字节。比如charAt(0)就会获得第一个汉子,charAt(1)就会获得第二个汉子,如果存储了符号或字母,或数字也占一个字节。比如字符串"我abc是"用string.getbyte("utf-8").length()获取的是9,直接length获取的是5,charAt1是a,charAt0是我
「已注销」 2015-10-27
  • 打赏
  • 举报
回复
个人建议,保存 UTF-8 这种本来就是 char 类型的东西,就直接用 char 或者 BYTE。不要用 CString 既当输入又当输出的。这个 CString 在 MBCS 下是 CStringA,在 Unicode 下是 CStringW,C++ 的操作符重载很方便,但有时也会带来麻烦。
「已注销」 2015-10-27
  • 打赏
  • 举报
回复
忘记了,你这里还是有个问题的,你不能用 CString 来保存 UTF-8 内容。如果你的项目是 Unicode 项目的话: strInfo = szUtf8; 这一行,实际上还会经历一层转换。毕竟 szUtf8 是 MBCS,而 strInfo 此时是 Unicode 编码的。
void ConvertGB2312ToUtf8_t(CString &strInfo)
{
#ifndef UNICODE
    int wcLength = MultiByteToWideChar(CP_ACP, 0, (LPCTSTR)strInfo, -1, NULL, 0);
    WCHAR *wszUnicode = new WCHAR[wcLength];
    int cchWideChars = MultiByteToWideChar(CP_ACP, 0, (LPCTSTR)strInfo, -1, wszUnicode, wcLength);
    if (GetLastError() != ERROR_INSUFFICIENT_BUFFER && cchWideChars > 0) {
#else
        WCHAR *wszUnicode = (LPCTSTR)strInfo;
#endif
        int mbLength = WideCharToMultiByte(CP_UTF8, 0, wszUnicode, -1, NULL, 0, NULL, NULL);
        char *szResult = new char[mbLength];
        int cbMultiBytes = WideCharToMultiByte(CP_UTF8, 0, wszUnicode, -1, szResult, mbLength, NULL,NULL);
        if (GetLastError() != ERROR_INSUFFICIENT_BUFFER && cbMultiBytes > 0) {
            // 当工程为 Unicode 时这里会调用又转为 Unicode:
            // const CString& CString::operator=(LPCSTR lpsz);
            // 内部参数是 CP_ACP 或当前进程的 CP,然而内容却是 UTF-8,转为 Unicode 肯定乱掉。
            strInfo = szResult;
        }
        delete[] szResult;
#ifndef UNICODE
    }
    delete[] wszUnicode;
#endif
}
「已注销」 2015-10-27
  • 打赏
  • 举报
回复
上面那么多贴代码的,我也是无语了。这代码没问题,问题在于: 1. UTF-8 的字符串 Windows 并不能显示,显示为问号是正常的。 你自己把两个都以二进制方式分别写入到 txt,然后用文本方式打开看看有没有问题就知道了。 2. URL 请求的时候必须要进行编码的,直接发送 ANSI 还是 UTF8 的原字符串都没用的。 把 UTF-8 原始 URL 字符串进行编码,转换为 %XX%XX 这种格式之后,再请求就可以了。 其实我说的两点,上面已经有人指出了。
用户 昵称 2015-10-26
  • 打赏
  • 举报
回复
系统只支持mbcs或utf16 little两种输出,其他的像utf8, utf7, utf16 big都要转成这两种才能正确输出,或者写入带bom头的文件中,现在的文本工具都支持多种字符集。
用户 昵称 2015-10-26
  • 打赏
  • 举报
回复
输入方法有问题。
ATMCash4423 2015-10-23
  • 打赏
  • 举报
回复
http://www.debugease.com/vc/1104110.html http://blog.csdn.net/erick08/article/details/8559123 以上两个并没有很好的解决这个问题,还请大家看看
赵4老师 2015-10-23
  • 打赏
  • 举报
回复
要用UrlEncode
ATMCash4423 2015-10-23
  • 打赏
  • 举报
回复
我碰到的的实际问题是这样的,我调用这个url下载这个文件,奇数汉字时tomcat报错“Invalid URI character encoding; trying ascii”,并返回HTTP错误代码400,意思大概是无法解析请求,偶数汉字时不报错。所以我怀疑是编码时出了问题。
snlux 2015-10-23
  • 打赏
  • 举报
回复
MultiByteToWideChar(CP_ACP,...) WideCharToMultiByte(CP_ACP,...)
zwfgdlc 2015-10-23
  • 打赏
  • 举报
回复
引用 5 楼 ATMCash4423 的回复:
我的是是VC2005,直接在strInfo = szUtf8; 下断点看的,工程是多字节工程,不是宽字符。 奇怪,我像你一样存成文件就没问题,但是断点看就不行,有?号
当然是问号了,VS并不支持直接显示UTF8编码文字. 只能支持ANSI,也就是GBK,或者UNICODE两种编码
ATMCash4423 2015-10-23
  • 打赏
  • 举报
回复
我的是是VC2005,直接在strInfo = szUtf8; 下断点看的,工程是多字节工程,不是宽字符。 奇怪,我像你一样存成文件就没问题,但是断点看就不行,有?号
zwfgdlc 2015-10-23
  • 打赏
  • 举报
回复
void ConvertGB2312ToUtf8_t(CStringA& strInfo)
{
	int len = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)strInfo, -1, NULL, 0);
	LPWSTR ucs = new WCHAR[len];
	memset(ucs, 0, len*2);
	MultiByteToWideChar(CP_ACP, 0, (LPCSTR)strInfo, -1, (LPWSTR)ucs, len);

	len = WideCharToMultiByte(CP_UTF8, 0, (LPWSTR)ucs, -1, NULL, 0, NULL, NULL);
	char *szUtf8 = new char[len];
	memset(szUtf8, 0, len);
	len = WideCharToMultiByte(CP_UTF8, 0, (LPWSTR)ucs, -1, szUtf8, len, NULL, NULL);

	strInfo = szUtf8;
	delete[] szUtf8;
	delete[] ucs;
}
CStringA dre = "http://192.168.0.84:8080/publish/taskfile/SMS20151023104800001/多手段测试.zip";
ConvertGB2312ToUtf8_t(dre);

FILE* fp;
fopen_s(&fp, "d:\\123.txt", "wb,ccs=utf-8");
fwrite(dre.GetBuffer(), dre.GetLength() + 1, 1, fp);
fclose(fp);
试了下写入到文件完全没问题,不知道你怎么测试的.
ATMCash4423 2015-10-23
  • 打赏
  • 举报
回复
引用 2 楼 zwfgdlc 的回复:

void ConvertGB2312ToUtf8_t(CStringA& strInfo)
{
	int len = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)strInfo, -1, NULL, 0);
	LPWSTR ucs = new WCHAR[len];
	memset(ucs, 0, len*2);
	MultiByteToWideChar(CP_ACP, 0, (LPCSTR)strInfo, -1, (LPWSTR)ucs, len);

	len = WideCharToMultiByte(CP_UTF8, 0, (LPWSTR)ucs, -1, NULL, 0, NULL, NULL);
	char *szUtf8 = new char[len];
	memset(szUtf8, 0, len);
	len = WideCharToMultiByte(CP_UTF8, 0, (LPWSTR)ucs, -1, szUtf8, len, NULL, NULL);

	strInfo = szUtf8;
	delete[] szUtf8;
	delete[] ucs;
}
试下这样


void ConvertGB2312ToUtf8(CStringA& strInfo)
{
	int len = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)strInfo, -1, NULL, 0);
	LPWSTR ucs = new WCHAR[len];
	memset(ucs, 0, len*2);
	MultiByteToWideChar(CP_ACP, 0, (LPCSTR)strInfo, -1, (LPWSTR)ucs, len);

	len = WideCharToMultiByte(CP_UTF8, 0, (LPWSTR)ucs, -1, NULL, 0, NULL, NULL);
	char *szUtf8 = new char[len];
	memset(szUtf8, 0, len);
//不行,,还是乱码。上面都执行的没问题,但是执行下面这句立刻出现问号。
	len = WideCharToMultiByte(CP_UTF8, 0, (LPWSTR)ucs, -1, szUtf8, len, NULL, NULL);

	strInfo = szUtf8;
	delete[] szUtf8;
	delete[] ucs;
}
zwfgdlc 2015-10-23
  • 打赏
  • 举报
回复

void ConvertGB2312ToUtf8_t(CStringA& strInfo)
{
	int len = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)strInfo, -1, NULL, 0);
	LPWSTR ucs = new WCHAR[len];
	memset(ucs, 0, len*2);
	MultiByteToWideChar(CP_ACP, 0, (LPCSTR)strInfo, -1, (LPWSTR)ucs, len);

	len = WideCharToMultiByte(CP_UTF8, 0, (LPWSTR)ucs, -1, NULL, 0, NULL, NULL);
	char *szUtf8 = new char[len];
	memset(szUtf8, 0, len);
	len = WideCharToMultiByte(CP_UTF8, 0, (LPWSTR)ucs, -1, szUtf8, len, NULL, NULL);

	strInfo = szUtf8;
	delete[] szUtf8;
	delete[] ucs;
}
试下这样

16,470

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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