零贰'Blog

零贰'Blog - 记录日常点点滴滴..........

VC 6.0下如何将汉字转换为utf-8网页转义编码

学习编程

#####阅读原文

在VC++ 6.0下要实现如下功能,将汉字转换为utf-8格式 和google类似 比如在google下搜索 “汉字”,自动生成连接http://www.google.cn/search?hl=zh-CN&q=%E6%B1%89%E5%AD%97&meta=&aq=f&oq= 其中“%E6%B1%89%E5%AD%97”就是“汉字”的utf-8编码吧 我也想得到这样一串数据,在C++怎么实现呢?期待高手。。。。。。。。。。。 更多 1 分享到:

发表于: 2009-03-12 16:38:53 楼主 对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理 回复次数:14 csdn官网 csdn官网 官方推荐 Android设计模式学习之观察者模式 关注CSDN程序人生公众号,轻松获得下载积分 JavaEE 6及以上版本的web.xml问题? 大数据技术丛书《数据挖掘:实用案例分析》 Android 图片毛玻璃的实现方法 声卡采集 core audio api java+EE+API中文版 Halcyon数据库连接 目标检测和跟踪小结 如何将编码转换为UTF-8

hairetz hairetz 猫已经找不回了 T9 Blank Blank Blank 更多勋章 http://www.aghost.cn/blog/article.asp?id=145 这个你看如何? 回复于: 2009-03-12 17:14:58 #1 得分:15 对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理 akirya akirya 珍惜生命远离CPP T9 Blank Blank Blank 更多勋章 这是转utf-8的,剩下的都容易 C/C++ code ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 //LPCSTR pASCIIBuf 要转换的ascii字符串指针 //LPSTR pUtf8Buf=NULL 转换成Utf8编码的字符串指针 //返回值 如果pUtf8Buf为0 则返回需要pUtf8Buf长度 int AToUtf8(LPCSTR pASCIIBuf,LPSTR pUtf8Buf=NULL) { if (NULL==pASCIIBuf) return 0; // ZeroMemory( wch, sizeof(WCHAR)*RECV_BUF ); DWORD UniCodeLen=MultiByteToWideChar(CP_ACP, 0, pASCIIBuf, -1, 0, 0); AUTO_NEW(wch,unsigned short,UniCodeLen); MultiByteToWideChar(CP_ACP, 0, pASCIIBuf, -1, wch, UniCodeLen); DWORD dwUtf8Len=WideCharToMultiByte(CP_UTF8, 0, wch, UniCodeLen , NULL, NULL, NULL, NULL ); if (NULL==pUtf8Buf) return dwUtf8Len; return WideCharToMultiByte(CP_UTF8, 0, wch, UniCodeLen , pUtf8Buf, dwUtf8Len, NULL, NULL ); } 回复于: 2009-03-12 17:18:25 #2 得分:35 对我有用[1] 丢个板砖[0] 引用 | 举报 | 管理 cnStreamlet cnStreamlet cnStreamlet T3 C/C++ code ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 //////////////////////////////////////////////////////////////////////////////// // // 文件名: UTF8.cpp // 作者: 溪流 // 创建时间: 2009-1-22 20:25:02 // 描述: 编码转换。暂时只有 Unicode 转为 UTF-8 的功能。 // ////////////////////////////////////////////////////////////////////////////////

#include “StdAfx.h” #include “Encoding.h”

////////////////////////////////////////////////////////////////////////////////

// UTF-8 定义: // U-00000000 - U-0000007F: 0xxxxxxx // U-00000080 - U-000007FF: 110xxxxx 10xxxxxx // U-00000800 - U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx // (以下是 UCS-4 了) // U-00010000 - U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx // U-00200000 - U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx // U-04000000 - U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx // 后面的 xxxx 用原来 Unicode 中的位依次填充

/// @brief Unicode 字符转换为 UTF-8 字符 /// @param buf [out] UTF-8 字符缓冲区,最大可能需要 6 个字节 /// @param bufSize buf 的大小,单位是字节 /// @param src [in] 源 Unicode 字符 /// @return 失败返回 -1,成功返回转换后 UTF-8 字符所占的字节数。 /// 如果缓冲区过小(bufSize 指示),则返回需要的字节数。 int CEncoding::WCharToUTF8(char *buf, int bufSize, const wchar_t src) { int bytesCount = 0;

wchar_t firstByte;    // 从 Unicode 中取出二进制位作为 UTF-8 第一字节时的掩码
char utfFirstByte;    // 为 UTF-8 第一字节加前导的若干个 1 要用的掩码

wchar_t wTmp;
char tmp;

if (src == 0)
{
    return -1;
}

if (src <= 0x7f)    // 01111111, ASCII
{
    bytesCount = 1;
    firstByte = 0x7f;            // 0111 1111
    utfFirstByte = (BYTE)0x00;    // 0000 0000
}
else if (src <= 0x7ff)    // 1000 0000 - 0111 1111 1111,有效位数 11 位
{
    bytesCount = 2;
    firstByte = 0x1f;            // 0001 1111,除去后一字节的 6 位,还剩 5 位
    utfFirstByte = (BYTE)0xc0;    // 1100 0000
}
else if (src <= 0xffff)    // 1000 0000 0000 - 1111 1111 1111 1111,16 位
{
    bytesCount = 3;
    firstByte = 0x0f;            // 0000 1111,除去后两字节的 12 位,还剩 4 位
    utfFirstByte = (BYTE)0xe0;    // 1110 0000
}
// UCS-4 支持
else if (src <= 0x001fffff)    // 计算方法下同,不再赘述
{
    bytesCount = 4;
    firstByte = 0x07;
    utfFirstByte = (BYTE)0xf0;
}
else if (src <= 0x03ffffff)
{
    bytesCount = 5;
    firstByte = 0x03;
    utfFirstByte = (BYTE)0xf8;
}
else if (src <= 0x7fffffff)
{
    bytesCount = 6;
    firstByte = 0x01;
    utfFirstByte = (BYTE)0xfc;
}
// 提供的值不符合 Unicode 定义
else
{
    return -1;
}

if (bufSize >= bytesCount)
{
    wTmp = src;
    for (int i = bytesCount - 1; i > 0; i--)    // 从低位往高位处理
    {
        tmp = (char)(wTmp & 0x3f);    // 取得低 6 位
        buf[i] = tmp | 0x80;    // 将最高 2 位变为 10
        wTmp >>= 6;
    }

    // 后面若干字节都处理完了,现在处理第一个字节
    tmp = (char)(wTmp & firstByte);    // 取出源字符中的剩余若干位
    buf[0] = (tmp | utfFirstByte);    // 高位或上若干个 1
}

return bytesCount;

}

/// @brief 字符转换为 UTF-8 字符 /// @param buf [out] UTF-8 字符串缓冲区 /// @param bufSize buf 的大小,单位是字节 /// @param src [in] 源 Unicode 字符串 /// @return 返回转换后 UTF-8 字符串所占的字节数。如果缓冲区过小(bufSize 指示), /// 那么仅转换到前 bufSize -1 个字节,第 bufSize 字节填零,返回 bufSize。 /// 可以用根据返回值是否小于原来提供的 bufSize 来判断缓冲区是否足够大。 int CEncoding::WCharStringToUTF8(char *buf, int bufSize, wchar_t *src) { int i = 0; while (*src != 0) { if (i >= bufSize) { buf[i - 1] = ‘\0’; return i; }

    i += CEncoding::WCharToUTF8(buf + i, bufSize - i, *src++);
}

buf[i] = '\0';

return i;

}

//////////////////////////////////////////////////////////////////////////////// 回复于: 2009-03-12 20:19:39 #3 得分:35 对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理 cnStreamlet cnStreamlet cnStreamlet T3 上面第一个函数是 Unicode 字符转 UTF-8 字符的,第二个函数是 Unicode 字符串转 UTF-8 字符串的 在程序中用 L’a’、L”12313” 就能得到 Unicode 的

之后对于 UTF-8 字符串中每一个字节,都用 16 进制输出,前面加上 % 就好了 回复于: 2009-03-12 20:23:54 #4 得分:15 对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理 qcbb001 qcbb001 大宝 T1 终于搞定了 不容易 楼上说的应该也可以实现 ,看下我的代码!

#include #include #include “windows.h” // 把UTF-8转换成Unicode void UTF_8ToUnicode(WCHAR* pOut,char pText) { char uchar = (char *)pOut;

uchar[1] = ((pText[0] & 0x0F) << 4) + ((pText[1] >> 2) & 0x0F); uchar[0] = ((pText[1] & 0x03) << 6) + (pText[2] & 0x3F);

return; } // Unicode 转换成UTF-8 void UnicodeToUTF_8(char* pOut,WCHAR* pText) { // 注意 WCHAR高低字的顺序,低字节在前,高字节在后 char* pchar = (char *)pText;

pOut[0] = (0xE0 | ((pchar[1] & 0xF0) >> 4)); pOut[1] = (0x80 | ((pchar[1] & 0x0F) << 2)) + ((pchar[0] & 0xC0) >> 6); pOut[2] = (0x80 | (pchar[0] & 0x3F));

return; }

// 把Unicode 转换成 GB2312 void UnicodeToGB2312(char* pOut,unsigned short uData) { WideCharToMultiByte(CP_ACP,NULL,&uData,1,pOut,sizeof(WCHAR),NULL,NULL); return; }

// GB2312 转换成 Unicode void Gb2312ToUnicode(WCHAR* pOut,char *gbBuffer) { ::MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,gbBuffer,2,pOut,1); return; }

//GB2312 转为 UTF-8 void GB2312ToUTF_8(CString& pOut,char pText, int pLen) { char buf[1024]; char rst = new char[pLen + (pLen >> 2) + 2];

memset(buf,0,1024); memset(rst,0,pLen + (pLen >> 2) + 2);

int i = 0; int j = 0;
while(i < pLen) { //如果是英文直接复制就可以 if( *(pText + i) >= 0) { rst[j++] = pText[i++]; } else { WCHAR pbuffer; Gb2312ToUnicode(&pbuffer,pText+i);

UnicodeToUTF_8(buf,&pbuffer);

unsigned short int tmp = 0; tmp = rst[j] = buf[0]; tmp = rst[j+1] = buf[1]; tmp = rst[j+2] = buf[2];

j += 3; i += 2; } } strcpy(&rst[j],”\0”);

//返回结果 pOut = rst;
delete []rst;

return; }

//UTF-8 转为 GB2312 void UTF_8ToGB2312(CString &pOut, char *pText, int pLen) { char * newBuf = new char[pLen]; char Ctemp[4]; memset(Ctemp,0,4);

int i =0; int j = 0;

while(i < pLen) { if(pText[i] > 0) { newBuf[j++] = pText[i++];
} else
{ WCHAR Wtemp; UTF_8ToUnicode(&Wtemp,pText + i);

UnicodeToGB2312(Ctemp,Wtemp);

newBuf[j] = Ctemp[0]; newBuf[j + 1] = Ctemp[1];

i += 3;
j += 2;
} } strcpy(&newBuf[j],”\0”);

pOut = newBuf; delete []newBuf;

return; }

CString UTF8_Encode(LPTSTR strUnicode)
{
long TLen ;
CString UTF8_EncodeLong ;

TLen = CString(strUnicode).GetLength() ;

if(TLen == 0)
{
return CString(strUnicode);
}

long lngBufferSize ;
long lngResult ;

//Set buffer for longest possible string.
lngBufferSize = TLen * 3 + 1 ;
char *bytUtf8 = new char[lngBufferSize] ;

//Translate using code page 65001(UTF-8).

lngResult = WideCharToMultiByte(CP_UTF8, 0, (unsigned short*)strUnicode, TLen, bytUtf8, lngBufferSize, NULL, 0) ;

bytUtf8[lngResult] = NULL ;

return CString(bytUtf8) ; }

/*************************************************************************/

CString URLEncode(CString sIn) { CString sOut; const int nLen = sIn.GetLength() + 1; register LPBYTE pOutTmp = NULL; LPBYTE pOutBuf = NULL; register LPBYTE pInTmp = NULL; LPBYTE pInBuf =(LPBYTE)sIn.GetBuffer(nLen); BYTE b = 0; //alloc out buffer

pOutBuf = (LPBYTE)sOut.GetBuffer(nLen*3 - 2);//new BYTE [nLen * 3]; if(pOutBuf) { pInTmp = pInBuf; pOutTmp = pOutBuf; // do encoding

while (*pInTmp) { if(isalnum(*pInTmp)) *pOutTmp++ = *pInTmp; else if(isspace(*pInTmp)) *pOutTmp++ = ‘+’; else // if(*pInTmp<=127) // *pOutTmp++ = *pInTmp; // else { *pOutTmp++ = ‘%’;

*pOutTmp++ = toHex(*pInTmp>>4);

*pOutTmp++ = toHex(*pInTmp%16); }

pInTmp++;

}

*pOutTmp = ‘\0’;

//sOut=pOutBuf;

//delete [] pOutBuf;

sOut.ReleaseBuffer();

}

sIn.ReleaseBuffer();

return sOut;

} 使用///////////////////////////////////

CString memname=“汉字”; GB2312ToUTF_8(memname,mem_name,TCBUFSIZE); URLEncode(memname)便是所要的结果”“%E6%B1%89%E5%AD%97”了。

回复于: 2009-03-16 17:05:21 #5 得分:0 对我有用[1] 丢个板砖[0] 引用 | 举报 | 管理 aoxueqilin aoxueqilin aoxueqilin T1 toHex 是什么函数啊?在这里好像缺少这个函数的定义。 回复于: 2009-03-18 11:53:48 #6 得分:0 对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理 aoxueqilin aoxueqilin aoxueqilin T1 toHex 是什么函数啊?在这里好像缺少这个函数的定义。 回复于: 2009-03-18 12:47:55 #7 得分:0 对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理 qcbb001 qcbb001 大宝 T1 引用 6 楼 aoxueqilin 的回复: toHex 是什么函数啊?在这里好像缺少这个函数的定义。

inline BYTE toHex(const BYTE &x) { return x > 9 ? x + 55: x + 48; }

不好意思 没贴全! 更正下使用

使用/////////////////////////////////// char *mem_name = “汉字”; CString memname=“”; GB2312ToUTF_8(memname,mem_name,TCBUFSIZE); URLEncode(memname)便是所要的结果”“%E6%B1%89%E5%AD%97”了。

回复于: 2009-03-19 09:12:09 #8 得分:0 对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理 xieyingfeichina xieyingfeichina xieyingfeichina T1 非常好的示例,研究很深入啊,高手,太感谢了 回复于: 2010-07-21 10:28:25 #9 得分:0 对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理 silver307 silver307 silver307 T1 非常好的示例,研究很深入啊 回复于: 2010-09-06 11:07:47 #10 得分:0 对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理 windseeker2008 windseeker2008 windseeker2008 T1 好,学习了 回复于: 2010-11-25 10:01:34 #11 得分:0 对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理 liaochuan1234 liaochuan1234 liaochuan1234 T1 引用 2 楼 akirya 的回复: 这是转utf-8的,剩下的都容易 C/C++ code //LPCSTR pASCIIBuf 要转换的ascii字符串指针 //LPSTR pUtf8Buf=NULL 转换成Utf8编码的字符串指针 //返回值 如果pUtf8Buf为0 则返回需要pUtf8Buf长度 int AToUtf8(LPCSTR pASCIIBuf,LPSTR pUtf8Buf=NULL) { if (NU……

我用了可以