1.WHAT
------1)标准C++提供了两种字符串:一种是C语言风格以“\0”字符结尾的字符数组;另一种是字符串类String。而Qt给我们提供的字符串类QString功能更强大。
------2)QString类保存16位Unicode值,提供了丰富的操作,查询和转换等函数。
2.HOW(需要包含头文件<QString>)
------1)字符串的操作:创建字符串对象(测试项目是QWidget的基类,无UI)- //创建字符串对象
- QString s1("hello"); //使用字符常量构造:const char *
- QString s2 = "qt"; //使用赋值构
------2)字符串拼接
---------①QString也提供了一个二元的“+”操作符用于组合两个字符串,并提供了“+=”操作符用于将一个字符串追加到另一个字符串的末尾(运算符重载),也可用append追加字符串。- //运算符重载,拼接字符串
- QString s3 =s1+s2;
- qDebug() <<"s3="<<s3; //s3= "hello qt"
- s3 += "!"; //或者+=QString对象
- qDebug() <<"s3="<<s3; //s3= "hello qt!"
- //append方式追加
- QString s4 = "hello";
- s4.append(" world!"); //使用append方式追加
- qDebug() <<"s4="<<s4; //s4= "hello world!
---------②QString::sprintf();//不常用,功能和C++定义一样,设计到编码问题qt中很少使用,尤其涉及到使用变量组包的时候- //sprintf方式实现:很少用
- QString s10;
- s10.sprintf("%s","Welcom1e");
- qDebug() <<"s10="<<s10; //s10= "Welcom1e"
- s10.sprintf("%s","to you!");
- qDebug()<<"s10="<<s10; //s10= "to you!"
- s10.sprintf("%s %s","Welcome","to you!");
- qDebug() <<"s10="<<s10; //s10= "Welcome to you!"
---------③QString::arg(); //常用的组包方式
此函数可以重载处理很多种数据类型,此外,一些重载具有额外的参数,对字段的宽度、整型、浮点型的精度进行控制。通常,相对于函数QString::sprintf(),这个函数是一个比较好的解决方案,因为类型安全,完全支持Unicode,允许改变“%n”参数的顺序,例如:- //QString::arg();
- QString s20 = "yongheng0";
- int n = 852;
- QString s21 = QString("%1.%2%4.%3").arg("www").arg(s20).arg("com").arg(n);
- qDebug()<<"s21="<<s21; //s21= "www.yongheng0852.com"
- //等价于
- QString s22 = "www." +s20 + QString::number(n)+ ".com";
- qDebug() <<"s22="<<s22; //s22= "www.yongheng0852.com"
------------a)%1:使用“arg("www")”替换
------------b)%2:使用 字符串对象“arg(s20)”的内容yongheng0替换
------------c)%4:使用 整型变量“arg(n)”的内容 852 替换
------------d)%3:使用“arg("com")”替换
------------e)等价于:22 = "www." +s20 + QString::number(n)+ ".com";//但这种+的方式不利于格式化方式组包。
---------④ 其他方式的字符串操作:QString也提供了一些其他组合字符串的方法包括以下几种:
------------a)insert()在字符串的任意位置插入一个字符串- //insert()在字符串的任意位置插入一个字符串
- QString s30 = "yongheng.com";
- QString s31 = "0852";
- s30.insert(8,&s31); //在字符串第8个位置插入s31这个字符串
- qDebug() <<"s30="<<s30; //s30= "yongheng0852.com"
------------b)prepend()在字符串的开头位置插入一个字符串- s30.prepend("www.");
- qDebug() <<"s30="<<s30; //s30= "www.yongheng0852.com"
------------c)replace()字符串替换- s30.replace("www","http://www"); //把www替换为http方式
- qDebug()<<"s30="<<s30; //s30= "http://www.yongheng0852.com"
------------d)trimmed()移除两端的空白字符- //trimmed()移除两端的空白字符
- QString s40 = " www.\tyongheng0852.\ncom ";
- qDebug()<<"s40="<<s40; //s40= " www.\tyongheng0852.\ncom "
- s40 = s40.trimmed(); //返回一个去除空格的对象
- qDebug() <<"s40="<<s40; //s40= "www.\tyongheng0852.\ncom"
------------b)simplified()移除两端空表字符和中间的特殊转义字符(转义字符用空格替换)- //simplified()移除两端空表字符和中间的特殊转移字符(用空格替换)
- QString s41 = " hello\nworld\t! ";
- qDebug()<<"s41="<<s41; //s41= " hello\nworld\t! "
- s41 = s41.simplified();
- qDebug()<<"s41="<<s41; //s41= "hello world !"
------3)查询字符串的数据
---------①startsWith(); 以某个字符串开头
(有两个参数,第一个参数是需要查找的字符串,第二个参数是,是否区分大小写,第二个参数可以不写,默认是区分大小写的)
(Sensitive:敏感的; Insensitive 不敏感的)- QString s50 = "www.yongheng0852.com";
- qDebug()<<s50.startsWith("www."); //默认区分大小写,返回true
- qDebug()<<s50.startsWith("wWw."); //默认区分大小写,返回false
- qDebug()<<s50.startsWith("wWw",Qt::CaseSensitive); //区分大小写.返回false
- qDebug()<<s50.startsWith("wWw",Qt::CaseInsensitive); //忽略大小写,返回true
---------②endWith(); 以某个字符串结尾(和startWith用法类似)- qDebug() << s50.endsWith("coM",Qt::CaseInsensitive); //忽略大小写,返回true
---------③ contains();判断是否包含某个字符串- qDebug()<<s50.contains("yongHENG",Qt::CaseSensitive); //区分大小写:false
- qDebug()<<s50.contains("yongHENG",Qt::CaseInsensitive); //不区分大小写:true
------4)比较字符串大小
和c/c++一样是以ascii码的方式比较字符串,当第一个字符不相同时,结果就确定,不会再继续向下面比较。 a<z(ascii)
---------①运算符重载"<,<=,==<,>,>="; 运算符左边的ascii码和右边的ascii逐位比较,结果为bool类型。- QString s60 = "cabc";
- //重载比较运算符,返回bool
- qDebug() << (s60 < "b"); //false
- qDebug() << (s60 <= "b"); //false
- qDebug()<< (s60 == "b"); //false
- qDebug()<< (s60 > "b"); //true
- qDebug() << (s60 >= "b"); //true
- qDebug() << (s60 < "d"); //true
---------②localeAwareCompare();使用本地字符集locale比较,返回整型,大于返回正整数,等于返回0,小于返回负整数
(有两个参数,分别为需要比较的字符串)- int ret = 0;
- ret =QString::localeAwareCompare(s60,"abcdef"); //ret= 1
- qDebug()<<"ret="<<ret;
- ret =QString::localeAwareCompare(s60,"cabc"); //ret= 0
- qDebug() <<"ret="<<ret;
- ret =QString::localeAwareCompare(s60,"gabcef"); //ret= -1
- qDebug() <<"ret="<<ret;
---------③QString::compare();可指定区分大小写的比较,如果不相等,返回值和localeAwareCompare的返回值方式类似。- ret = QString::compare("bcd","bcd"); //默认区分大小写:0
- qDebug() <<"ret="<<ret;
- ret = QString::compare("bcd","Bcd"); //默认区分大小写:32
- qDebug() <<"ret="<<ret;
- ret = QString::compare("bcd","Bcd",Qt::CaseSensitive); //区分大小写:32
- qDebug() <<"ret="<<ret;
- ret = QString::compare("bcd","Bcd",Qt::CaseInsensitive); //不区分大小写:0
- qDebug()<<"ret="<<ret;
------5)字符串转换
---------①字符串 --> 基础数据(int等):
函数原型:(int QString::toInt(bool *ok = Q_NULLPTR, int base = 10) const)
参数1接收转换的结果,转成功为true,失败false,参数2,是指定字符串内的原始数据是多少进制的,也就是说,是需要把字符串中的数据是以多少进制转换为10进制。)
参数1和参数2可以不指定,参数1不指定时,不接收转换结果。
参数2不指定时默认字符串中的数据是10进制的)
参数2不指定时,默认为10进制,如果设置为0时,则会使用c语言的转换方法,即:如果字符串以“0x”开头,则基数为16,如果以“0”开头,则基数为8,其他情况,基数都为10;
------------a)QString::toInt(无参数); - QString s70 = "0168";
- int a70 = s70.toInt();
- qDebug()<<"a70="<<a70; //a70= 168
-
- s70 = "0.168";
- double a71 = s70.toDouble();
- qDebug() <<"a71="<<a71; //a71= 0.168
-
- s70 = "hello qt";
- a70 = s70.toInt();
- qDebug()<<"a70="<<a70; //转换失败,数据为0
---------②QString::toInt(参数1,参数2); 对转换结果进行判断,并按照指定的进制基数进行转换。- bool ok = false;
- s70 = "0168";
- a70 = s70.toInt(&ok,16); //指定字符串中的数据是16进制,把他转换为10进制
- if(ok)
- {
- qDebug()<<"s70 = 0168:"<<"16进制转换10进制成功,数据是:"<<a70; //数据是:360
- }
- else
- {
- qDebug()<<"s70 = 0168:"<<"16进制转换10进制失败!";
- }
-
- s70 = "0167"; //如果数据超过了8进制的范围,则转换失败
- a70 = s70.toInt(&ok,8);
- if(ok)
- {
- qDebug()<<"s70 = 0167:"<<"8进制转换10进制成功,数据是:"<<a70; //数据是:119
- }
- else
- {
- qDebug()<<"s70 = 0167:"<<"8进制转换10进制失败!";
- }
-
- s70 = "hello qt";
- a70 = s70.toInt(&ok); //不指定第二个参数默认转换为10进制
- if(ok)
- {
- qDebug()<<"s70 = hello qt :"<<"转换成功,数据是:"<<a70;
- }
- else
- {
- qDebug()<<"s70 = hello qt :"<<"转换失败!"; //数据转换失败
- }
---------②基础数据(int等) --> 字符串:
------------a)QString::arg(); 组包的方式:- int b = 100;
- QString s80 = QString("%1").arg(b);
- qDebug() <<"s80="<<s80; //s80= "100"
------------b)QString::number(); 更简便的方式:- b = 200;
- s80 = QString::number(b);
- qDebug()<<"s80="<<s80; //s80= "200"
-
- double d = 0.852;
- s80 = QString::number(d);
- qDebug() <<"s80="<<s80; //s80= "0.852"
---------③标准string和QTstring的互换(引入了c++的iostream的头文件,和string头文件)- //QString 转C++ string:
- QString q_str1 = "hello";
- std::string c_str1 = q_str1.toStdString();
- std::cout<<"QString 转C++ string="<<c_str1<<std::endl;
-
- //C++ string 转QString:
- std::string c_str2 = "world";
-
- QString q_str2 = QString::fromStdString(c_str2);
- qDebug()<<"C++ string 转QString="<<q_str2;
------6)NULL字符串和Empty空字符串的区别
一个NULL字符串是使用QString的默认构造或者使用“(const char*)0”作为参数的构造函数创建的QString字符串对象;而一个空字符串是一个大小为0的字符串,一个NULL字符串一定是一个字符串,而一个空字符串未必是一个NULL字符串。例如:- QString s81 = QString();
- qDebug()<<s81.isNull(); //true
- qDebug()<<s81.isEmpty(); //true
-
- QString s82 = QString("");
- qDebug()t<<s82.isNull(); //false
- qDebug()<<s82.isEmpty(); //true
-
- qDebug()<<"以下代码和上面等价:";
- qDebug()<<QString().isNull(); //true
- qDebug()<<QString().isEmpty(); //true
- qDebug()<<QString("").isNull(); //false
- qDebug()<<QString("").isEmpty(); //true
------7)工程项目是创建了一个 QWidget的基类的无UI项目,测试代码都写在widget.cpp的构造函数里面。
---------①代码:- #include "widget.h"
- #include<QString>
- #include<QDebug>
-
- #include <iostream>
- #include <string> //c++的string类
-
- Widget::Widget(QWidget *parent)
- : QWidget(parent)
- {
- //创建字符串对象--------------------------------------
- QString s1("hello"); //使用字符常量构造:const char *
- QString s2 = " qt"; //使用赋值构造
-
- qDebug()<<"--------------运算符重载,拼接字符串--------------";
- QString s3 =s1+s2;
- qDebug() <<"s3="<<s3; //s3= "hello qt"
- s3 += "!"; //或者+=QString对象
- qDebug() <<"s3="<<s3; //s3= "hello qt!"
- //append方式追加
- QString s4 = "hello";
- s4.append(" world!"); //使用append方式追加
- qDebug() <<"s4="<<s4; //s4= "hello world!"
-
-
- qDebug()<<"--------------sprintf方式实现:很少用--------------";
- QString s10;
- s10.sprintf("%s","Welcom1e");
- qDebug() <<"s10="<<s10; //s10= "Welcom1e"
- s10.sprintf("%s","to you!");
- qDebug() <<"s10="<<s10; //s10= "to you!"
- s10.sprintf("%s %s","Welcome","to you!");
- qDebug() <<"s10="<<s10; //s10= "Welcome to you!"
-
- qDebug()<<"--------------组包:QString::arg()--------------";
- QString s20 = "yongheng0";
- int n = 852;
- QString s21 = QString("%1.%2%4.%3").arg("www").arg(s20).arg("com").arg(n);
- qDebug() <<"s21="<<s21; //s21= "www.yongheng0852.com"
- //等价于
- QString s22 = "www." +s20 + QString::number(n)+ ".com";
- qDebug() <<"s22="<<s22; //s22= "www.yongheng0852.com"
-
- qDebug()<<"--------------其他组合字符串的方式--------------";
- //insert()在字符串的任意位置插入一个字符串
- QString s30 = "yongheng.com";
- QString s31 = "0852";
- s30.insert(8,&s31); //在字符串第8个位置插入s31这个字符串
- qDebug() <<"s30="<<s30; //s30= "yongheng0852.com"
- //prepend()在字符串的开头位置插入一个字符串
- s30.prepend("www.");
- qDebug() <<"s30="<<s30; //s30= "www.yongheng0852.com"
-
- qDebug()<<"--------------replace()字符串替换--------------";
- s30.replace("www","http://www"); //把www替换为http方式
- qDebug() <<"s30="<<s30; //s30= "http://www.yongheng0852.com"
-
- qDebug()<<"--------------trimmed()移除两端的空白字符--------------";
- QString s40 = " www.\tyongheng0852.\ncom ";
- qDebug() <<"s40="<<s40; //s40= " www.\tyongheng0852.\ncom "
- s40 = s40.trimmed(); //返回一个去除空格的对象
- qDebug() <<"s40="<<s40; //s40= "www.\tyongheng0852.\ncom"
-
- //simplified()移除两端空表字符和中间的特殊转移字符(用空格替换)
- QString s41 = " hello\nworld\t! ";
- qDebug() <<"s41="<<s41; //s41= " hello\nworld\t! "
- s41 = s41.simplified();
- qDebug() <<"s41="<<s41; //s41= "hello world !"
-
- //查询字符串数据-----------------------------------------
- qDebug()<<"--------------以某个字符串开头或结尾:s50--------------";
- QString s50 = "www.yongheng0852.com";
- qDebug()<<s50.startsWith("www."); //默认区分大小写,返回true
- qDebug()<<s50.startsWith("wWw."); //默认区分大小写,返回false
- qDebug()<<s50.startsWith("wWw",Qt::CaseSensitive); //区分大小写.返回false
- qDebug()<<s50.startsWith("wWw",Qt::CaseInsensitive); //忽略大小写,返回true
-
- //以某个字符串结尾(和startWith用法类似)
- qDebug() << s50.endsWith("coM",Qt::CaseInsensitive); //忽略大小写,返回true
-
- //判断是否包含某个字符串
- qDebug()<<"判断是否包含某个字符串:s50";
- qDebug()<<s50.contains("yongHENG",Qt::CaseSensitive); //区分大小写:false
- qDebug()<<s50.contains("yongHENG",Qt::CaseInsensitive); //不区分大小写:true
-
- //比较字符串大小:以ascii码的大小比较,a<z----------------------------
- qDebug()<<"--------------比较字符串大小:s60--------------";
- QString s60 = "cabc";
- //重载比较运算符,返回bool
- qDebug() << (s60 < "b"); //false
- qDebug() << (s60 <= "b"); //false
- qDebug() << (s60 == "b"); //false
- qDebug() << (s60 > "b"); //true
- qDebug() << (s60 >= "b"); //true
- qDebug() << (s60 < "d"); //true
- //使用本地字符集locale比较,返回整型,大于返回正整数,等于返回0,小于返回负整数
- int ret = 0;
- ret =QString::localeAwareCompare(s60,"abcdef"); //ret= 1
- qDebug() <<"ret="<<ret;
- ret =QString::localeAwareCompare(s60,"cabc"); //ret= 0
- qDebug() <<"ret="<<ret;
- ret =QString::localeAwareCompare(s60,"gabcef"); //ret= -1
- qDebug() <<"ret="<<ret;
- //可指定区分大小写的比较,如果不相等,返回值和localeAwareCompare的返回值方式类似
- ret = QString::compare("bcd","bcd"); //默认区分大小写:0
- qDebug() <<"ret="<<ret;
- ret = QString::compare("bcd","Bcd"); //默认区分大小写:32
- qDebug() <<"ret="<<ret;
- ret = QString::compare("bcd","Bcd",Qt::CaseSensitive); //区分大小写:32
- qDebug() <<"ret="<<ret;
- ret = QString::compare("bcd","Bcd",Qt::CaseInsensitive); //不区分大小写:0
- qDebug() <<"ret="<<ret;
-
- //字符串转换----------------------------
- qDebug()<<"--------------字符串->数据(int等)--------------";
- QString s70 = "0168";
- int a70 = s70.toInt();
- qDebug() <<"a70="<<a70; //a70= 168
-
- s70 = "0.168";
- double a71 = s70.toDouble();
- qDebug() <<"a71="<<a71; //a71= 0.168
-
- s70 = "hello qt";
- a70 = s70.toInt();
- qDebug() <<"a70="<<a70; //转换失败,数据为0
-
- //对转换结果进行判断-----------------------
- bool ok = false;
- s70 = "0168";
- a70 = s70.toInt(&ok,16); //指定字符串中的数据是16进制,把他转换为10进制
- if(ok)
- {
- qDebug()<<"s70 = 0168:"<<"16进制转换10进制成功,数据是:"<<a70; //数据是:360
- }
- else
- {
- qDebug()<<"s70 = 0168:"<<"16进制转换10进制失败!";
- }
-
- s70 = "0167"; //如果数据超过了8进制的范围,则转换失败
- a70 = s70.toInt(&ok,8);
- if(ok)
- {
- qDebug()<<"s70 = 0167:"<<"8进制转换10进制成功,数据是:"<<a70; //数据是:119
- }
- else
- {
- qDebug()<<"s70 = 0167:"<<"8进制转换10进制失败!";
- }
-
- s70 = "hello qt";
- a70 = s70.toInt(&ok); //不指定第二个参数默认转换为10进制
- if(ok)
- {
- qDebug()<<"s70 = hello qt :"<<"转换成功,数据是:"<<a70;
- }
- else
- {
- qDebug()<<"s70 = hello qt :"<<"转换失败!"; //数据转换失败
- }
-
- //数字转换为字符串
- qDebug()<<"--------------数字转换为字符串--------------";
- int b = 100;
- QString s80 = QString("%1").arg(b);
- qDebug() <<"s80="<<s80; //s80= "100"
-
- b = 200;
- s80 = QString::number(b);
- qDebug() <<"s80="<<s80; //s80= "200"
-
- double d = 0.852;
- s80 = QString::number(d);
- qDebug() <<"s80="<<s80; //s80= "0.852"
-
- //QString 转C++ string:
- QString q_str1 = "hello";
- std::string c_str1 = q_str1.toStdString();
- std::cout<<"QString 转C++ string="<<c_str1<<std::endl;
-
- //C++ string 转QString:
- std::string c_str2 = "world";
-
- QString q_str2 = QString::fromStdString(c_str2);
- qDebug()<<"C++ string 转QString="<<q_str2;
-
- qDebug()<<"--------------NULL字符串和空字符串的区别--------------";
- QString s81 = QString();
- qDebug()<<s81.isNull(); //true
- qDebug()<<s81.isEmpty(); //true
- QString s82 = QString("");
- qDebug()<<s82.isNull(); //false
- qDebug()<<s82.isEmpty(); //true
-
- qDebug()<<"以下代码和上面等价:";
- qDebug()<<QString().isNull(); //true
- qDebug()<<QString().isEmpty(); //true
- qDebug()<<QString("").isNull(); //false
- qDebug()<<QString("").isEmpty(); //true
-
-
- }
-
- Widget::~Widget()
- {
-
- }
---------②运行结果- --------------运算符重载,拼接字符串--------------
- QString 杞珻++ string=hello //标准c++的字符串在qt中的编码问题导致乱码
- s3= "hello qt"
- s3= "hello qt!"
- s4= "hello world!"
- --------------sprintf方式实现:很少用--------------
- s10= "Welcom1e"
- s10= "to you!"
- s10= "Welcome to you!"
- --------------组包:QString::arg()--------------
- s21= "www.yongheng0852.com"
- s22= "www.yongheng0852.com"
- --------------其他组合字符串的方式--------------
- s30= "yongheng0852.com"
- s30= "www.yongheng0852.com"
- --------------replace()字符串替换--------------
- s30= "http://www.yongheng0852.com"
- --------------trimmed()移除两端的空白字符--------------
- s40= " www.\tyongheng0852.\ncom "
- s40= "www.\tyongheng0852.\ncom"
- s41= " hello\nworld\t! "
- s41= "hello world !"
- --------------以某个字符串开头或结尾:s50--------------
- true
- false
- false
- true
- true
- 判断是否包含某个字符串:s50
- false
- true
- --------------比较字符串大小:s60--------------
- false
- false
- false
- true
- true
- true
- ret= 1
- ret= 0
- ret= -1
- ret= 0
- ret= 32
- ret= 32
- ret= 0
- --------------字符串->数据(int等)--------------
- a70= 168
- a71= 0.168
- a70= 0
- s70 = 0168: 16进制转换10进制成功,数据是: 360
- s70 = 0167: 8进制转换10进制成功,数据是: 119
- s70 = hello qt : 转换失败!
- --------------数字转换为字符串--------------
- s80= "100"
- s80= "200"
- s80= "0.852"
- C++ string 转QString= "world"
- --------------NULL字符串和空字符串的区别--------------
- true
- true
- false
- true
- 以下代码和上面等价: true
- true
- false
- true
---------③注意事项,虽然字符串有NULL和Empyt,但是 QString A(); cout<<A.isNull(); 这种定义方式是编译不同过的(面试题)。
---------④完整的代码(注意解压后不能有中文路径)5_1_1_Qt字符串类QString的基本使用.zip(见个人博客)
3.WHY
------1)主要的原因,在 Qt中使用了标准c++的string类时,由于编码问题,很多中文的字符串,在qt中显示出来的都是乱码,使用QTstring,处理编码问题很方便。