您的位置:首页 > 编程语言

字符串和十六进制数的转换(总结网上的代码)

2014-09-19 12:10 176 查看
因为用到的转换功能都需要在Qt中实现,所以先介绍一下QString、string和char*的转换

1、QString转换为string

usingnamespacestd;//添加命名空间

QStringstr;
stringmyString=str.toStdString();


2、string转换为QString

usingnamespacestd;

stringmyString;
QStringmyQString=QString::fromStdString(myString);


3、QString转换为char*

QStringmyQString;
char*p=(char*)myQString.toStdString().c_str();


4、char*转换为QString

char*p;
QStringmyQString=QString(p);


6、字符串和十六进制数转换

//十六进制数组转为字符串
//参数HexData为数组指针
//参数iLen为数组长度
//返回值为对应的十六进制字符串
stringHexToStr(constunsignedchar*HexData,intiLen);

//字符串转为十六进制数
//参数strData为字符串形式的十六进制值
//参数HexData为数组指针
//参数iLen为数组HexData的长度
//返回值为0表示转换成功,非0则表示转换失败
//(返回1表示长度不匹配)
//(返回2表示字符串中包含非十六进制的字符)
intStrToHex(stringstrData,unsignedchar*HexData,intiLen);


staticconstcharNum_Hex[16]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};

//十六进制数组转为字符串
//参数HexData为数组指针
//参数iLen为数组长度
//返回值为对应的十六进制字符串
stringHexToStr(constunsignedchar*HexData,intiLen)
{
stringstrRet;
unsignedcharucTmp;
for(inti=0;i<iLen;i++)
{
ucTmp=*(HexData+i);
strRet+=Num_Hex[(ucTmp>>4)&0x0f];
strRet+=Num_Hex[ucTmp&0x0f];
}
returnstrRet;
}
//字符串转为十六进制数
//参数strData为字符串形式的十六进制值
//参数HexData为数组指针
//参数iLen为数组HexData的长度
//返回值为0表示转换成功,非0则表示转换失败
//(返回1表示长度不匹配)
//(返回2表示字符串中包含非十六进制的字符)
intStrToHex(stringstrData,unsignedchar*HexData,intiLen)
{
intiRet=0;
unsignedcharucTmp;
transform(strData.begin(),strData.end(),strData.begin(),::toupper);//字符串转为大写
intsz=strData.size();
if(sz!=2*iLen)
return1;
for(inti=0;i<sz;i++)
{
ucTmp=strData.at(i);
//0-9的ASCII码为0x30-0x39,A-F的ASCII码为0x41-0x46
if(!((ucTmp>=0x30&&ucTmp<=0x39)||(ucTmp>=0x41&&ucTmp<=0x46)))
return2;
}
sz=sz/2;
for(inti=0;i<sz;i++)
{
ucTmp=strData.at(2*i);
if(ucTmp>=0x30&&ucTmp<=0x39)
{
ucTmp-=0x30;
}
elseif(ucTmp>=0x41&&ucTmp<=0x46)
{
ucTmp-=0x37;
}
*(HexData+i)=ucTmp<<4;

ucTmp=strData.at(2*i+1);
if(ucTmp>=0x30&&ucTmp<=0x39)
{
ucTmp-=0x30;
}
elseif(ucTmp>=0x41&&ucTmp<=0x46)
{
ucTmp-=0x37;
}
*(HexData+i)+=ucTmp;
}
returniRet;
}


transform(strData.begin(),strData.end(),strData.begin(),::toupper);//字符串转为大写


代码说明:为什么要加::toupper

在<cctype>里面声明了一个C版本的函数tolower,inttolower(int);而在<local>中间也声明了一个函数模板:

template<classcharT>
charTtolower(charTc,constlocale&loc);


如果这两个头文件都同时包含到程序中来的话(C++标准头文件可能会包含另外的标准头文件。例如有的编译器在一些标准头文件中,如<iostream>,会包含<locale>或<cctype>头文件。这样,包含<iostream>可能会引入<locale>或<cctype>),由于这些tolower函数都位于同一std名字空间,于是形成了函数重载。这样的话,transform函数(也是一个模板函数)的第四个参数是tolower的时候,此时给定的tolower只是作为一个函数指针使用,缺乏类型推导所需要的函数参数信息,所以无法推导出函数的类型,也就无法决定使用哪一个重载函数。

如果想使用非模版的tolower函数,有多种方法可以解决:

transform(s.begin(),s.end(),s.begin(),(int(*)(int))tolower);

或者:

int(*pf)(int)=tolower;//pf是一个函数指针,其类型已经明确。
transform(s.begin(),s.end(),s.begin(),pf);

或者:

//使用一个包装函数,避免直接使用tolower函数由于重载带来的问题。
intmy_tolower(intc)
{
returntolower(c);//根据c的类型可以确定使用tolower的哪个重载函数。
}


//…

//my_tolower是非模版非重载函数,避免了函数重载带来的类型解析问题。

transform(s.begin(),s.end(),s.begin(),my_tolower);

另外,非模板函数的tolower其实是来自于标准C库函数,因此在
C++标准库中它同时位于全局和std名字空间。既然std名字空间内tolower函数有可能形成函数重载,但是在全局名字空间中的
tolower函数却只有一个,所以也可以直接使用全局名字空间中的tolower:

transform(s.begin(),s.end(),s.begin(),::tolower);


当然,模板函数和非模板函数tolower的区别还是很明显的:前者有两个参数,后者只有一个参数。而程序中使用的transform函数的第四个参数要求,如果是函数的话只能是有一个参数的函数,所以从这方面来说重载函数的选择问题是可以得到解决的。有的编译器可能就是根据这一点做了进一步的判别处理,或者直接选择了非模版函数,从而解决了这一问题。但是C++标准并没有要求一定要解决类似的不确定问题,所以无论编译器是怎样处理的,解决或者没有解决,应该都是符合标准的。

至此,问题成功解决。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: