代码:很详细的教程
//testqstring.cpp
#include <QApplication>
#include <QTextBrowser>
#include <QDebug>
#include <QTextStream>
#include <QTextCodec> //添加头文件
void Test_setNum()
{
QString strTest;
//to Hex string
short numHex = 127;
strTest.setNum(numHex, 16);
qDebug()<<"Hex: "<<strTest;
//to Oct string
int numOct = 63;
strTest.setNum(numOct, 8);
qDebug()<<"Oct: "<<strTest;
//to normal Dec string
long numDec = 800;
strTest.setNum(numDec);
qDebug()<<"Normal: "<<strTest;
//to float string
float numFixed = 123.78999;
strTest.setNum(numFixed, 'f', 3);
qDebug()<<"Fixed: "<<strTest;
//to scientific double string
double numScientific = 456.78999;
strTest.setNum(numScientific, 'e', 6);
qDebug()<<"Scientific: "<<strTest;
}
void Test_arg()
{
//使用 strResult 存储 arg 返回的新对象
QString strResult;
//Dec
long numDec = 800;
QString strMod = QObject::tr("Normal: %1");
strResult = strMod.arg(numDec); //%1是占位符,第一个arg函数参数变量转后的字符串填充到 %1 位置
qDebug()<<"Mod: "<<strMod<<" \t Result: "<<strResult;
//Oct
int numOct = 63;
strResult = QObject::tr("Oct: %1").arg(numOct, 4, 8, QChar('0')); //numOct转换后为4字符域宽,8进制,填充0
qDebug()<<strResult;
//Hex
short numHex = 127;
QString strPrefix = QObject::tr("0x");
//占位符里可填充数值转的字符串,也可以直接填充原有的字符串
strResult = QObject::tr("Hex: %1%2").arg(strPrefix).arg(numHex, 0, 16); //串联:第一个arg函数参数填充到%1,第二个arg填充到%2
qDebug()<<strResult;
//double
double numReal = 123.78999;
strResult = QObject::tr("Fixed: %1 \t Scientific: %2").arg(numReal, 0, 'f').arg(numReal, 0, 'e', 3);
qDebug()<<strResult;
//占位符可重复,也可乱序
int one = 1;
int two = 2;
int three = 3;
strResult = QObject::tr("%1 小于 %2,%1 小于 %3,%3 大于 %2 。").arg(one).arg(two).arg(three);
qDebug()<<strResult;
}
void Test_toValue()
{
bool bok = false;
//dec
QString strDec = QObject::tr("800");
int nDec = strDec.toInt(&bok, 10);
qDebug()<<nDec<<"\t"<<bok; //成功
//Hex
QString strHex = QObject::tr("FFFF");
nDec = strHex.toInt(&bok, 10); //基数错误,转换失败
qDebug()<<nDec<<"\t"<<bok;
short nHexShort = strHex.toShort(&bok, 16);
qDebug()<<nHexShort<<"\t"<<bok; //FFFF正整数太大,超出范围,转换失败,没有负号 - 的都算正数。
ushort nHexUShort = strHex.toUShort(&bok, 16);
qDebug()<<nHexUShort<<"\t"<<bok;//成功
//自动转换
QString strOct = QObject::tr("0077");
int nOct = strOct.toInt(&bok, 0);
qDebug()<<nOct<<"\t"<<bok; //字符 0 打头自动按八进制转
QString strHexWithPre = QObject::tr("0xFFFF");
int nHexWithPre = strHexWithPre.toInt(&bok, 0);
qDebug()<<nHexWithPre<<"\t"<<bok; //字符 0x 打头自动按十六进制转
int nDecAuto = strDec.toInt(&bok, 0); //"800" ,自动按十进制
qDebug()<<nDecAuto<<"\t"<<bok;
//浮点数转换
QString strFixed = QObject::tr("123.78999");
double dblFixed = strFixed.toDouble(&bok);
qDebug()<<fixed<<dblFixed<<"\t"<<bok;
//科学计数法
QString strScientific = QObject::tr("1.238e-5");
double dblScientific = strScientific.toDouble(&bok);
qDebug()<<scientific<<dblScientific<<"\t"<<bok;
}
void Test_operator()
{
// =
QString strE1, strE2, strE3;
strE1 = QObject::tr("abcd");
strE2 = strE1;
strE3 = strE2;
//打印数据指针
qDebug()<<strE1.data_ptr()<<"\t"<<strE2.data_ptr()<<"\t"<<strE3.data_ptr();
//改变字符串,追加
strE2.append( QObject::tr("1234") );
//再次打印数据指针,谁修改了数据,谁的数据指针就变
qDebug()<<strE1.data_ptr()<<"\t"<<strE2.data_ptr()<<"\t"<<strE3.data_ptr();
// += 和 append 函数类似
strE3 += QObject::tr("1234");
qDebug()<<strE2<<"\t"<<strE3;
//比较 1 vs 2
qDebug()<<"strE1 < strE2: "<<(strE1 < strE2);
qDebug()<<"strE1 <= strE2: "<<(strE1 <= strE2);
qDebug()<<"strE1 == strE2: "<<(strE1 == strE2);
qDebug()<<"strE1 != strE2: "<<(strE1 != strE2);
//2 vs 3
qDebug()<<"strE2 > strE3"<<(strE2 > strE3);
qDebug()<<"strE2 >= strE3"<<(strE2 >= strE3);
qDebug()<<"strE2 == strE3"<<(strE2 == strE3);
//类似数组取数
qDebug()<<strE1[0];
strE1[0] = QChar('?'); //修改
qDebug()<<strE1;
//拼接
QString strPlus;
strPlus = strE1 + strE2 + strE3;
qDebug()<<strPlus;
}
void Test_substring()
{
QString strOne = QObject::tr("abcd");
QString strThree = strOne.repeated(3); //abcd 重复三次
qDebug()<<strThree.isEmpty(); //是否为空
qDebug()<<strThree.length()<<"\t"<<strThree.size(); //都是长度
qDebug()<<strThree;
//子串查询
qDebug()<<strThree.contains(strOne); //是否包含
qDebug()<<strThree.count(strOne); //包含几个
qDebug()<<strThree.startsWith(strOne); //打头的子串
qDebug()<<strThree.indexOf(strOne); //左边开始的子串位置
qDebug()<<strThree.lastIndexOf(strOne); //右边开始的子串位置
//剔除两端的空白
QString strComplexFileName = QObject::tr(" /home/user/somefile.txt \t\t ");
QString strFileName = strComplexFileName.trimmed();
qDebug()<<strFileName;
if(strFileName.endsWith( QObject::tr(".txt") ))
{
qDebug()<<"This is a .txt file";
}
//分隔子串
QStringList subsList = strFileName.split(QChar('/'));
for(int i=0; i<subsList.length(); i++) //打印各个子串
{
qDebug()<<i<<"\t"<<subsList[i];
}
//获取段落
QString subsections = strFileName.section(QChar('/'), 2, 3);
qDebug()<<subsections;
}
void Test_QTextStream()
{
//内存输出流
QString strOut;
QTextStream streamOut(&strOut);
//打印多种进制数字
streamOut<<800<<endl;
streamOut<<hex<<127<<endl;
streamOut<<oct<<63<<endl;
//还原为十进制
streamOut<<dec;
//设置域宽和填充字符
streamOut<<qSetFieldWidth(8)<<qSetPadChar('0')<<800;
//还原默认域宽和填充
streamOut<<qSetFieldWidth(0)<<qSetPadChar(' ')<<endl;
//设置精度
streamOut<<qSetRealNumberPrecision(3)<<fixed<<123.789999<<endl;
streamOut<<qSetRealNumberPrecision(6)<<scientific<<123.789999<<endl;
//打印字符串和数字混搭
streamOut<<QObject::tr("7*7 == ")<<7*7<<endl;
//显示现在的字符串对象
qDebug()<<strOut;
//内存输入流
QString strIn = QObject::tr("800 abcd 123.789999");
QTextStream streamIn(&strIn);
int numDec = 0;
QString strSub;
double dblReal = 0.0;
//输入到变量里
streamIn>>numDec>>strSub>>dblReal;
//显示
qDebug()<<numDec;
qDebug()<<strSub;
qDebug()<<fixed<<dblReal; //定点数显示
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// QTextCodec::setCodecForTr(QTextCodec::codecForLocale()); //使程序中可以使用中文
// QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF8"));
// QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF8"));
QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF8"));
QString strText = QObject::tr("测试 QString");
QTextBrowser tb;
tb.setText(strText);
tb.setGeometry(40, 40, 400, 300);
tb.show();
//setNum
Test_setNum();
//arg
//Test_arg();
//toValue
//Test_toValue();
//operator
//Test_operator();
//substring
//Test_substring();
//QTextStream
//Test_QTextStream();
return a.exec();
}
void Test_setNum()
{
QString strTest;
//to Hex string
short numHex = 127;
strTest.setNum(numHex, 16);
qDebug()<<"Hex: "<<strTest;
//to Oct string
int numOct = 63;
strTest.setNum(numOct, 8);
qDebug()<<"Oct: "<<strTest;
//to normal Dec string
long numDec = 800;
strTest.setNum(numDec);
qDebug()<<"Normal: "<<strTest;
//to float string
float numFixed = 123.78999;
strTest.setNum(numFixed, 'f', 3);
qDebug()<<"Fixed: "<<strTest;
//to scientific double string
double numScientific = 456.78999;
strTest.setNum(numScientific, 'e', 6);
qDebug()<<"Scientific: "<<strTest;
}
//运行结果
/******************************************* Hex: "7f" Oct: "77" Normal: "800" Fixed: "123.790" Scientific: "4.567900e+02" *******************************************/
void Test_arg()
{
//使用 strResult 存储 arg 返回的新对象
QString strResult;
//Dec
long numDec = 800;
QString strMod = QObject::tr("Normal: %1");
strResult = strMod.arg(numDec); //%1是占位符,第一个arg函数参数变量转后的字符串填充到 %1 位置
qDebug()<<"Mod: "<<strMod<<" \t Result: "<<strResult;
//Oct
int numOct = 63;
strResult = QObject::tr("Oct: %1").arg(numOct, 4, 8, QChar('0')); //numOct转换后为4字符域宽,8进制,填充0
qDebug()<<strResult;
//Hex
short numHex = 127;
QString strPrefix = QObject::tr("0x");
//占位符里可填充数值转的字符串,也可以直接填充原有的字符串
strResult = QObject::tr("Hex: %1%2").arg(strPrefix).arg(numHex, 0, 16); //串联:第一个arg函数参数填充到%1,第二个arg填充到%2
qDebug()<<strResult;
//double
double numReal = 123.78999;
strResult = QObject::tr("Fixed: %1 \t Scientific: %2").arg(numReal, 0, 'f').arg(numReal, 0, 'e', 3);
qDebug()<<strResult;
//占位符可重复,也可乱序
int one = 1;
int two = 2;
int three = 3;
strResult = QObject::tr("%1 小于 %2,%1 小于 %3,%3 大于 %2 。").arg(one).arg(two).arg(three);
qDebug()<<strResult;
}
//运行结果
/************************************************
Mod: "Normal: %1" Result: "Normal: 800"
"Oct: 0077"
"Hex: 0x7f"
"Fixed: 123.789990 Scientific: 1.238e+02"
"1 小于 2,1 小于 3,3 大于 2 。"
*************************************************/
void Test_toValue()
{
bool bok = false;
//dec
QString strDec = QObject::tr("800");
int nDec = strDec.toInt(&bok, 10);
qDebug()<<nDec<<"\t"<<bok; //成功
//Hex
QString strHex = QObject::tr("FFFF");
nDec = strHex.toInt(&bok, 10); //基数错误,转换失败
qDebug()<<nDec<<"\t"<<bok;
short nHexShort = strHex.toShort(&bok, 16);
qDebug()<<nHexShort<<"\t"<<bok; //FFFF正整数太大,超出范围,转换失败,没有负号 - 的都算正数。
ushort nHexUShort = strHex.toUShort(&bok, 16);
qDebug()<<nHexUShort<<"\t"<<bok;//成功
//自动转换
QString strOct = QObject::tr("0077");
int nOct = strOct.toInt(&bok, 0);
qDebug()<<nOct<<"\t"<<bok; //字符 0 打头自动按八进制转
QString strHexWithPre = QObject::tr("0xFFFF");
int nHexWithPre = strHexWithPre.toInt(&bok, 0);
qDebug()<<nHexWithPre<<"\t"<<bok; //字符 0x 打头自动按十六进制转
int nDecAuto = strDec.toInt(&bok, 0); //"800" ,自动按十进制
qDebug()<<nDecAuto<<"\t"<<bok;
//浮点数转换
QString strFixed = QObject::tr("123.78999");
double dblFixed = strFixed.toDouble(&bok);
qDebug()<<fixed<<dblFixed<<"\t"<<bok;
//科学计数法
QString strScientific = QObject::tr("1.238e-5");
double dblScientific = strScientific.toDouble(&bok);
qDebug()<<scientific<<dblScientific<<"\t"<<bok;
}
/***************************** 800 true 0 false 0 false 65535 true 63 true 65535 true 800 true 123.789990 true 1.238000e-05 true ******************************/
void Test_operator()
{
// =
QString strE1, strE2, strE3;
strE1 = QObject::tr("abcd");
strE2 = strE1;
strE3 = strE2;
//打印数据指针
qDebug()<<strE1.data_ptr()<<"\t"<<strE2.data_ptr()<<"\t"<<strE3.data_ptr();
//改变字符串,追加
strE2.append( QObject::tr("1234") );
//再次打印数据指针,谁修改了数据,谁的数据指针就变
qDebug()<<strE1.data_ptr()<<"\t"<<strE2.data_ptr()<<"\t"<<strE3.data_ptr();
// += 和 append 函数类似
strE3 += QObject::tr("1234");
qDebug()<<strE2<<"\t"<<strE3;
//比较 1 vs 2
qDebug()<<"strE1 < strE2: "<<(strE1 < strE2);
qDebug()<<"strE1 <= strE2: "<<(strE1 <= strE2);
qDebug()<<"strE1 == strE2: "<<(strE1 == strE2);
qDebug()<<"strE1 != strE2: "<<(strE1 != strE2);
//2 vs 3
qDebug()<<"strE2 > strE3"<<(strE2 > strE3);
qDebug()<<"strE2 >= strE3"<<(strE2 >= strE3);
qDebug()<<"strE2 == strE3"<<(strE2 == strE3);
//类似数组取数
qDebug()<<strE1[0];
strE1[0] = QChar('?'); //修改
qDebug()<<strE1;
//拼接
QString strPlus;
strPlus = strE1 + strE2 + strE3;
qDebug()<<strPlus;
}
/*****************************************
0x3a8070 0x3a8070 0x3a8070
0x3a8070 0xce64858 0x3a8070
"abcd1234" "abcd1234"
strE1 < strE2: true
strE1 <= strE2: true
strE1 == strE2: false
strE1 != strE2: true
strE2 > strE3 false
strE2 >= strE3 true
strE2 == strE3 true
'a'
"?bcd"
"?bcdabcd1234abcd1234"
****************************************/
void Test_substring()
{
QString strOne = QObject::tr("abcd");
QString strThree = strOne.repeated(3); //abcd 重复三次
qDebug()<<strThree.isEmpty(); //是否为空
qDebug()<<strThree.length()<<"\t"<<strThree.size(); //都是长度
qDebug()<<strThree;
//子串查询
qDebug()<<strThree.contains(strOne); //是否包含
qDebug()<<strThree.count(strOne); //包含几个
qDebug()<<strThree.startsWith(strOne); //打头的子串
qDebug()<<strThree.indexOf(strOne); //左边开始的子串位置
qDebug()<<strThree.lastIndexOf(strOne); //右边开始的子串位置
//剔除两端的空白
QString strComplexFileName = QObject::tr(" /home/user/somefile.txt \t\t ");
QString strFileName = strComplexFileName.trimmed();
qDebug()<<strFileName;
if(strFileName.endsWith( QObject::tr(".txt") ))
{
qDebug()<<"This is a .txt file";
}
//分隔子串
QStringList subsList = strFileName.split(QChar('/'));
for(int i=0; i<subsList.length(); i++) //打印各个子串
{
qDebug()<<i<<"\t"<<subsList[i];
}
//获取段落
QString subsections = strFileName.section(QChar('/'), 2, 3);
qDebug()<<subsections;
}
/***************************** false 12 12 "abcdabcdabcd" true 3 true 0 8 "/home/user/somefile.txt" This is a .txt file 0 "" 1 "home" 2 "user" 3 "somefile.txt" "user/somefile.txt" ****************************/
void Test_QTextStream()
{
//内存输出流
QString strOut;
QTextStream streamOut(&strOut);
//打印多种进制数字
streamOut<<800<<endl;
streamOut<<hex<<127<<endl;
streamOut<<oct<<63<<endl;
//还原为十进制
streamOut<<dec;
//设置域宽和填充字符
streamOut<<qSetFieldWidth(8)<<qSetPadChar('0')<<800;
//还原默认域宽和填充
streamOut<<qSetFieldWidth(0)<<qSetPadChar(' ')<<endl;
//设置精度
streamOut<<qSetRealNumberPrecision(3)<<fixed<<123.789999<<endl;
streamOut<<qSetRealNumberPrecision(6)<<scientific<<123.789999<<endl;
//打印字符串和数字混搭
streamOut<<QObject::tr("7*7 == ")<<7*7<<endl;
//显示现在的字符串对象
qDebug()<<strOut;
//内存输入流
QString strIn = QObject::tr("800 abcd 123.789999");
QTextStream streamIn(&strIn);
int numDec = 0;
QString strSub;
double dblReal = 0.0;
//输入到变量里
streamIn>>numDec>>strSub>>dblReal;
//显示
qDebug()<<numDec;
qDebug()<<strSub;
qDebug()<<fixed<<dblReal; //定点数显示
}
/******************************** "800 7f 77 00000800 123.790 1.237900e+02 7*7 == 49 " 800 "abcd" 123.789999 ********************************/
来自:Qt 编程指南 PS:写的很好很详细
Qt 最常用的字符串类是内码固定的 QString,而针对传统类似 C 语言 char* 的字符串,Qt 提供了 QByteArray 类来处理。QString 的字符单元是 QChar,QByteArray 的字节单元是 char。头文件 不仅自身以类的形式提供,它还针对传统 C 语言的字符串函数做了安全版本的封装,都加了 q 字母前缀,如 qstrlen、qstrncmp、qstrcpy,这些是全局函数,专门处理传统 C 语言的 char* 字符串,用法与 C 语言风格完全类似,比较简单,本节就不介绍了。本节主要介绍 QByteArray 类的使用。
QByteArray 类可以处理以 ‘\0’ 结尾的传统字符串,包括 UTF-8 编码和其他如 GBK、Big5 等多字节编码的字符串,在作为字符串使用时,QByteArray 内部字符编码格式是不限定的,可以是任意编码的,所以程序员自己必须要事先确定程序会用到哪些编码的 QByteArray 。因为 Qt5 源文件规定是 UTF-8 编码的,所以 QByteArray 内部使用 UTF-8 编码的字符串居多。QByteArray 在赋值、传参数、返回值时也是使用隐式共享机制提高运行效率,只有字符串发生修改时才会执行深拷贝。
在文件处理、网络数据收发等场景,QByteArray 类是作为纯字节数组来使用的,里面可以包含任意数据,比如一堆 ‘\0’,这时不要拿它当字符串看,它的存储长度与 qstrlen 计算的长度经常不一致。对于网络数据收发,QByteArray 经常配合 QDataStream 使用,对 Qt 数据类型做串行化(Serializing)。
void TestStr() //内码 UTF-8
{
//数值与字符串转换
int nDec = 800;
QByteArray basDec;
basDec.setNum(nDec); //数值转字符串
qDebug()<<basDec;
QByteArray basReal = "125.78999";
double dblReal = basReal.toDouble(); //字符串转数值
qDebug()<<fixed<<dblReal;
//运算符
QByteArray basABCD = "ABCD";
QByteArray basXYZ = "XYZ";
qDebug()<<(basABCD < basXYZ); //二者字符编码一致才能比较!
qDebug()<<(basABCD == basXYZ);
qDebug()<<(basABCD >= basXYZ);
qDebug()<<(basABCD + basXYZ);
//子串处理
QByteArray basHanzi = "1234打印汉字";
//作为字符串时 QByteArray::length() 和 qstrlen() 一致
qDebug()<<basHanzi.length()<<"\t"<<qstrlen( basHanzi.data() );
//重复
QByteArray basMoreHanzi = basHanzi.repeated(2);
qDebug()<<basMoreHanzi.count("1234"); //统计次数
qDebug()<<basMoreHanzi.startsWith("1234"); //开头判断
qDebug()<<basMoreHanzi.endsWith("汉字"); //结尾判断
qDebug()<<basMoreHanzi.indexOf("1234"); //从左边查出现位置
qDebug()<<basMoreHanzi.lastIndexOf("1234"); //从右边查出现位置
//替换
basMoreHanzi.replace("1234", "一二三四");
qDebug()<<basMoreHanzi;
//切割字符串
QByteArray basComplexFile = " /home/user/somefile.txt \t\t ";
QByteArray basFileName = basComplexFile.trimmed(); //剔除两端空白
qDebug()<<basFileName;
//分隔得到新的 QByteArray 对象列表
QList<QByteArray> baList = basFileName.split('/');
//打印
for(int i=0; i<baList.length(); i++)
{
qDebug()<<i<<"\t"<<baList[i];
}
//没有段落函数
}
上面测试函数第一段是数值与字符串互相转换的,比较简单,打印结果是:
“800”
125.789990
浮点数转换时,定点计数法和科学计数法都是可以接受的,上面示范的是定点数。这些函数声明和功能都可以查阅 QByteArray 类的帮助文档。
第二段代码是运算符函数的,需要注意的是一定要在确定字符串内部字符编码的情况下,才能进行比较和拼接,上面用的全是 UTF-8 。不能将不同编码格式的字符串比较,因为得到的结果没意义,反而会造成误导。上面比较运算符的打印结果为:
true
false
false
“ABCDXYZ”
第三段是子串查询处理的,注意只有当 QByteArray 作为字符串处理时,它的 length() 函数计算的长度才会和全局函数 qstrlen() 计算的结果一致。子串部分打印的结果为:
16 16
2
true
true
0
16
“一二三四打印汉字一二三四打印汉字”
上面示范的 basMoreHanzi.replace(“1234”, “一二三四”) ,这种形式的替换函数会对所有匹配的子串进行替换,它的声明是:
QByteArray & replace(const char * before, const char * after)
如果要对指定位置的子串替换,需要换一个声明形式的 replace 函数,比如:
QByteArray & replace(int pos, int len, const char * after)
这个函数会对指定位置 pos 开始的长度为 len 的子串进行替换,这个函数声明只做一次替换。
对于 replace 函数,必须注意字符编码的问题,UTF-8 的英文字符占用 1 字节,汉字通常是 3 字节,这种不确定性在替换函数和其他分隔子串函数时尤其需要注意,因为 3 字节的汉字如果被截断,就成错误的字符,造成信息损失。因此尽量不要用 QByteArray 类来处理字符串,尤其是涉及分割和替换的。QString 类的字符长度是固定的,所以最适合做字符串处理。
最后一段代码是子串分隔的,trimmed 函数功能也是去除两端的空白区域,split 函数将字符串分隔为多个子串之后按照 QList 类型返回,QList 是一个模板类,QList 就是存储多个 QByteArray 对象的列表,可以直接用中括号 [] 访问里面的各个对象。最后一段代码打印的结果如下:
“/home/user/somefile.txt”
0 “”
1 “home”
2 “user”
3 “somefile.txt”
分隔结果与上一节 QString 是一样的,对于开头 ‘/’ 左边没有字符的情况,一样会分出来一个空字符串对象。因为一般用 QString 来处理文本字符串,QByteArray 类没有 section 函数,所以字符串处理时优先用 QString 类。