字符串和十六进制数的转换(总结网上的代码)
2014-09-19 12:10
176 查看
因为用到的转换功能都需要在Qt中实现,所以先介绍一下QString、string和char*的转换
1、QString转换为string
2、string转换为QString
3、QString转换为char*
4、char*转换为QString
6、字符串和十六进制数转换
代码说明:为什么要加::toupper
在<cctype>里面声明了一个C版本的函数tolower,inttolower(int);而在<local>中间也声明了一个函数模板:
如果这两个头文件都同时包含到程序中来的话(C++标准头文件可能会包含另外的标准头文件。例如有的编译器在一些标准头文件中,如<iostream>,会包含<locale>或<cctype>头文件。这样,包含<iostream>可能会引入<locale>或<cctype>),由于这些tolower函数都位于同一std名字空间,于是形成了函数重载。这样的话,transform函数(也是一个模板函数)的第四个参数是tolower的时候,此时给定的tolower只是作为一个函数指针使用,缺乏类型推导所需要的函数参数信息,所以无法推导出函数的类型,也就无法决定使用哪一个重载函数。
如果想使用非模版的tolower函数,有多种方法可以解决:
//…
//my_tolower是非模版非重载函数,避免了函数重载带来的类型解析问题。
transform(s.begin(),s.end(),s.begin(),my_tolower);
另外,非模板函数的tolower其实是来自于标准C库函数,因此在
C++标准库中它同时位于全局和std名字空间。既然std名字空间内tolower函数有可能形成函数重载,但是在全局名字空间中的
tolower函数却只有一个,所以也可以直接使用全局名字空间中的tolower:
当然,模板函数和非模板函数tolower的区别还是很明显的:前者有两个参数,后者只有一个参数。而程序中使用的transform函数的第四个参数要求,如果是函数的话只能是有一个参数的函数,所以从这方面来说重载函数的选择问题是可以得到解决的。有的编译器可能就是根据这一点做了进一步的判别处理,或者直接选择了非模版函数,从而解决了这一问题。但是C++标准并没有要求一定要解决类似的不确定问题,所以无论编译器是怎样处理的,解决或者没有解决,应该都是符合标准的。
至此,问题成功解决。
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++标准并没有要求一定要解决类似的不确定问题,所以无论编译器是怎样处理的,解决或者没有解决,应该都是符合标准的。
至此,问题成功解决。
相关文章推荐
- 随手在网上找了一段将字节数组转换为十六进制字符串的代码,结果被坑惨了
- 随手在网上找了一段将字节数组转换为十六进制字符串的代码,结果被坑惨了
- 随手在网上找了一段将字节数组转换为十六进制字符串的代码,结果被坑惨了
- Date类学习总结(Calendar Date 字符串 相互转换 格式化)
- JasonHelper.Escape 转换字符串为jason格式代码
- C++数值--字符串间转换方法总结
- 字符串怎么转换成十六进制数?
- C++中字符串的相互转换总结(珍藏)
- c#实现16进制和字符串之间转换的代码
- ABAP--关于字符串String到XString XString to String转换代码
- Date类学习总结(Calendar Date 字符串 相互转换 格式化)
- (转)不同框架下的C++字符串代码转换
- vb和vc++中将字符串表示的16进制单精度浮点数转换成十进制数的代码
- Date类学习总结(Calendar Date 字符串 相互转换 格式化)
- 数据类型转换(代码总结)
- 字符串转换为日期总结
- Iconv是UNIX 95的iconv()函数的封装形式,它在各种字符代码体系间进行字符串转换。
- c#实现16进制和字符串之间转换的代码
- Oracle多行转换成字符串方法总结
- json格式和字符串格式的相互转换总结