消息关闭
    暂无新消息!
下面这段代码功能是 在linux系统下,将GBK编码的中英文特殊字符转换为十六进制
现在我想实现将十六进制转换为unicode编码,从unicode编码转换为gbk编码的我已经写好了
希望大神给点意见

#include <iostream>
#include <sstream>
#include <stdlib.h>
#include <string.h>
#include <iconv.h> 
#include <stdio.h>
#include <ctype.h>
using namespace std;


//编码转换,source_charset是源编码,to_charset是目标编码  
std::string code_convert(const char *source_charset,const char *to_charset, const std::string& sourceStr) //sourceStr是源编码字符串  
{  
    iconv_t cd = iconv_open(to_charset, source_charset);//获取转换句柄,void*类型  
    if (cd == 0)  
        return (string)"";  
  
    size_t inlen = sourceStr.size();
    size_t outlen = 1024;  
    char* inbuf = (char*)sourceStr.c_str();  
    char outbuf[outlen];//这里实在不知道需要多少个字节,这是个问题  
    //char *outbuf = new char[outlen]; 另外outbuf不能在堆上分配内存,否则转换失败,猜测跟iconv函数有关  
    memset(outbuf, 0, outlen);  
  
    char *poutbuf = outbuf; //多加这个转换是为了避免iconv这个函数出现char(*)[255]类型的实参与char**类型的形参不兼容  
    if (iconv(cd, &inbuf, &inlen, &poutbuf,&outlen) == -1)  
        return (string)"";   
  
    std::string strTemp(outbuf);//此时的strTemp为转换编码之后的字符串  
    iconv_close(cd);  
    return strTemp;  

std::string Gbk_to_unicode(const std::string& strInput)  
{  
    return code_convert("GBK", "UCS-2LE//IGNORE", (char*)strInput.c_str());  
}  
std::string unicode_to_Gbk(const std::string& strInput)  
{  
    return code_convert("UCS-2LE", "GBK//IGNORE", (char*)strInput.c_str());  
}  
//判断是大端还是小端
bool is_big_endian()  
{  
    unsigned short test = 0x1234;  
    if(*( (unsigned char*)&test ) == 0x12)  
        return true;  
    else  
        return false;  
}  

string UnicodetoHexString(int i) 
{
 stringstream ss;
 ss << hex  << i;
 return ss.str();
}

string toHexString(string& strInput)
{
int i = 0;
string strResult = "";
int num = strInput.length();
while(i < num)
{
if(strInput[i] >= 32 && strInput[i]<= 126)//ASCII码表值
{
strResult += UnicodetoHexString(strInput[i]);
}
else
{
string tmp = strInput.substr(i,2);//中文占两个字节
i++;
string strUnicode = Gbk_to_unicode(tmp);
int num = strUnicode.size();  
     unsigned char* p = (unsigned char*)strUnicode.c_str();   
     string strbuf[2];  
     for (int i = 0; i < num; i++)        
     {        
        strbuf[i] += UnicodetoHexString(*p);     
        p++;        
     }
     if (is_big_endian()) //大端系统
     {
     strResult += strbuf[0] + strbuf[1];
     }
     else//小端系统
     {
     strResult += strbuf[1] + strbuf[0];
     }  
}
i++;
}
return strResult;
}
int main()


string str= "abc中sfg国de_&%$$*f__12";
cout<<toHexString(str)<<endl;
return 0;
}

5个回答

︿ 3
//iconv_linux下字符集编码转换轻松实现
(1) iconv_t iconv_open(const char *tocode, const char *fromcode);
//此函数说明将要进行哪两种编码的转换,tocode是目标编码,fromcode是原编码,该函数返回一个转换句柄,供以下两个函数使用。
(2) size_t iconv(iconv_t cd,char **inbuf,size_t *inbytesleft,char **outbuf,size_t *outbytesleft);
//此函数从inbuf中读取字符,转换后输出到outbuf中,inbytesleft用以记录还未转换的字符数,outbytesleft用以记录输出缓冲的剩余空间。
(3) int iconv_close(iconv_t cd);
//此函数用于关闭转换句柄,释放资源。

//例子1: 用C语言实现的转换示例程序

/* f.c : 代码转换示例C程序 */
#include <iconv.h>
#define OUTLEN 255
main()
{
char *in_utf8 = "姝e?ㄥ??瑁?";
char *in_gb2312 = "正在安装";
char out[OUTLEN];

/*unicode码转为gb2312码*/
rc = u2g(in_utf8,strlen(in_utf8),out,OUTLEN);
printf("unicode-->gb2312 out=%sn",out);
//gb2312码转为unicode码

rc = g2u(in_gb2312,strlen(in_gb2312),out,OUTLEN);
printf("gb2312-->unicode out=%sn",out);
}
/*代码转换:从一种编码转为另一种编码*/
int code_convert(char *from_charset,char *to_charset,char *inbuf,int inlen,char *outbuf,int outlen)
{
iconv_t cd;
int rc;
char **pin = &inbuf;
char **pout = &outbuf;

cd = iconv_open(to_charset,from_charset);
if (cd==0) return -1;
memset(outbuf,0,outlen);
if (iconv(cd,pin,&inlen,pout,&outlen)==-1) return -1;
iconv_close(cd);
return 0;
}
/*UNICODE码转为GB2312码*/
int u2g(char *inbuf,int inlen,char *outbuf,int outlen)
{
return code_convert("utf-8","gb2312",inbuf,inlen,outbuf,outlen);
}
/*GB2312码转为UNICODE码*/
int g2u(char *inbuf,size_t inlen,char *outbuf,size_t outlen)
{
return code_convert("gb2312","utf-8",inbuf,inlen,outbuf,outlen);
}

//例子2: 用C++语言实现的转换示例程序

/* f.cpp : 代码转换示例C++程序 */
#include <iconv.h>
#include <iostream>

#define OUTLEN 255

using namespace std;

// 代码转换操作类

class CodeConverter {

private:
iconv_t cd;
public:

// 构造
CodeConverter(const char *from_charset,const char *to_charset) {
cd = iconv_open(to_charset,from_charset);
}


// 析构
~CodeConverter() {
iconv_close(cd);
}


// 转换输出
int convert(char *inbuf,int inlen,char *outbuf,int outlen) {
char **pin = &inbuf;
char **pout = &outbuf;

memset(outbuf,0,outlen);
return iconv(cd,pin,(size_t *)&inlen,pout,(size_t *)&outlen);
}
};

int main(int argc, char **argv)
{
char *in_utf8 = "姝e?ㄥ??瑁?";
char *in_gb2312 = "正在安装";
char out[OUTLEN];

// utf-8-->gb2312
CodeConverter cc = CodeConverter("utf-8","gb2312");
cc.convert(in_utf8,strlen(in_utf8),out,OUTLEN);
cout << "utf-8-->gb2312 in=" << in_utf8 << ",out=" << out << endl;

// gb2312-->utf-8
CodeConverter cc2 = CodeConverter("gb2312","utf-8");
cc2.convert(in_gb2312,strlen(in_gb2312),out,OUTLEN);
cout << "gb2312-->utf-8 in=" << in_gb2312 << ",out=" << out << endl;
}



二、利用iconv命令进行编码转换

iconv命令用于转换指定文件的编码,默认输出到标准输出设备,亦可指定输出文件。

用法: iconv [选项...] [文件...]

有如下选项可用:

输入/输出格式规范:
-f, --from-code=名称 原始文本编码
-t, --to-code=名称 输出编码

信息:
-l, --list 列举所有已知的字符集

输出控制:
-c 从输出中忽略无效的字符
-o, --output=FILE 输出文件
-s, --silent 关闭警告
--verbose 打印进度信息

-?, --help 给出该系统求助列表
--usage 给出简要的用法信息
-V, --version 打印程序版本号

例子:
iconv -f utf-8 -t gb2312 aaa.txt >bbb.txt
这个命令读取aaa.txt文件,从utf-8编码转换为gb2312编码,其输出定向到bbb.txt文件。

小结: Linux为我们提供了强大的编码转换工具,给我们带来了方便。


︿ 1
仅供参考:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>
int main() {
    int i,v;
    char bs[33];
    char b[33];
    char hs[9];
    char h[9];
    char s[4];
    char *e;

// 十进制整数转二进制串;
    i=1024;
    ltoa(i,b,2);
    sprintf(bs,"%032s",b);
    printf("i=%d,bs=%s\n",i,bs);
// 十进制整数转十六进制串;
    i=1024;
    ltoa(i,h,16);
    sprintf(hs,"%08s",h);
    printf("i=%d,hs=%s\n",i,hs);
// 十六进制字符串转成十进制数
    strcpy(hs,"00000400");
    sscanf(hs,"%x",&i);
    printf("hs=%s,i=%d\n",hs,i);
// 二进制字符串转化为十六进制字符串;
    strcpy(bs,"00000000000000000000010000000000");
    i=strtol(bs,&e,2);
    ltoa(i,h,16);
    sprintf(hs,"%08s",h);
    printf("bs=%s,hs=%s\n",bs,hs);
// 二进制字符串转化为十进制数;
    strcpy(bs,"00000000000000000000010000000000");
    i=strtol(bs,&e,2);
    printf("bs=%s,i=%d\n",bs,i);
// 十六进制字符串转成二进制串
    strcpy(hs,"00000400");
    sscanf(hs,"%x",&i);
    ltoa(i,b,2);
    sprintf(bs,"%032s",b);
    printf("hs=%s,bs=%s\n",hs,bs);
// ASC\GBK字符串转十六进制串
    strcpy(s,"a汉");
    i=0;
    while (1) {
        if (0==s[i]) break;
        sprintf(hs+i*2,"%02X",(unsigned char)s[i]);
        i++;
    }
    setlocale(LC_ALL,"chs");
    printf("s=%s,hs=%s\n",s,hs);
// 十六进制字符串转成汉字(GBK)及字符(ASC)
    strcpy(hs,"61BABA");
    i=0;
    while (1) {
        if (1!=sscanf(hs+i*2,"%2x",&v)) break;
        s[i]=(char)v;
        i++;
    }
    s[i]=0;
    printf("hs=%s,s=%s\n",hs,s);

    return 0;

}
//i=1024,bs=00000000000000000000010000000000
//i=1024,hs=00000400
//hs=00000400,i=1024
//bs=00000000000000000000010000000000,hs=00000400
//bs=00000000000000000000010000000000,i=1024
//hs=00000400,bs=00000000000000000000010000000000
//s=a汉,hs=61BABA
//hs=61BABA,s=a汉
︿ 0
十六进制数想不出来可以去转为unicode编码的方式,数字不好去区分。。。