QString 字符串操作

目录

一. QString 简介

1.QString 字符串的创建和初始化

2.QString 字符串的索引

二. QChar 的功能

1.QChar 类的主要接口函数

2.QChar 字符与 Latin1 字符的转换

3.QChar 字符的 Unicode 编码

4.QChar 的逻辑运算符

三. QString 字符串常用操作

1.字符串拼接

2.字符串截取

3.存储相关的函数

4.搜索和判断

5.字符串转换和修改

 四. QString 字符串与数值的转换

1.字符串转换为整数

2.字符串转换为浮点数

3.函数 setNum()

4.静态函数 number()

5.静态函数 asprintf()

6.函数 arg()

一. QString 简介

 QString 是 Qt 中的一个类,用于存储字符串,QString 没有父类。QString 存储的是一串字符,每个字符是一个 QChar 类型的数据。QChar 使用的是 UTF-16 编码,一个字符包含 2 字节数据。 对于超过 65535 的 Unicode 编码,QString 使用两个连续的 QChar 字符表示。UTF-16 是一种 Unicode 编码,能表示汉字,在 QString 字符串中一个汉字是一个字符。

 QString 类定义了大量的接口函数用于字符串操作。QString在 Qt 类库中应用非常广泛,很多函数的参数是 QString 类型。QString 使用隐式共享减少内存占用,也就是只有在修改一个字符串的时候,这个字符串才会被复制。

字符集与编码

ASCII 是基本的字符集,用 1 字节编码,数字 0~127 表示 128 个字符,包括英语中的大小写字母、数字 0~9、标点符号、换行符、制表符、退格符等。 Latin1 字符集是对 ASCII 字符集的扩展,也是用 1 字节编码,它用 128~255 表示拉丁字母表中特殊语言字符的编码。

ASCII 和 Latin1 都是用 1 字节编码的,最多只有 256 个字符,无法表示汉语、日语等其他语言里的字符,因此又出现了 Unicode 编码。 Unicode 编码增加一个或多个高字节对 Latin1 字节进行扩展。当这些高字节数据为 0 时,低字节数据就是 Latin1 字符。 Unicode 支持大多数国家/地区语言文字的编码,所以被广泛使用。

Unicode 有多种存储方案,其中 UTF-8 最少用 1 字节编码, 可以使用 1~4 字节编码; UTF-16 最少用 2 字节编码,可以使用 2 字节或 4 字节编码。 UTF-8 可以兼容 Latin1 编码,所以被广泛使用。 Qt Creator 存储的 C++语言头文件和源程序文件都默认使用 UTF-8 编码。

1.QString 字符串的创建和初始化

QString str = "Hello Qt";

在 Qt Creator 中,所有源程序文件都默认使用 UTF-8 编码进行保存,所以,赋值语句右侧的 “Hello Qt”是一个 C 语言标准的 const char *类型的字符串,以“\0”作为结束符。QString 会使用其静态函数 fromUtf8() 将这个 const char *类型的数据转换为 UTF-16 编码的字符串.

2.QString 字符串的索引

QString 在被创建和初始化后,其存储的字符串就是一个QChar 字符数组,可以使用元素索引操作符“[ ]”或接口函数 at() 访问每个字符。QString 字符串内字符的索引序号是从 0 开始的。

QString str= "dimple,酒窝"; 
QChar ch0= str[0]; //ch0='d' 
QChar ch7= str.at(7); //ch7='酒' 
//QChar ch9= str.at(9); //报错

在 QString 字符串中,每个字符都是 QChar 类型, 是用 UTF-16 编码的, 一个汉字也是一个字符。所以,在上面这段代码里,ch0 是字符“d”,ch7 是字符“酒”。如果访问位置为 9的字符,则会报错。

二. QChar 的功能

1.QChar 类的主要接口函数

QString 字符串中的每个字符都是 QChar 类型的,QChar 也是一个类, 它采用 UTF-16 编码表示字符。QChar 定义了很多接口函数用于字符操作,QChar 类的主要接口函数如表所示.

QChar 类的主要接口函数
函数原型功能介绍
bool isDigit()判断字符是否为 0~9 的数字
bool isLetter()判断字符是否为字母
bool isLetterOrNumber()判断字符是否为字母或数字
bool isLower()判断字符是否为小写字母
bool isUpper()判断字符是否为大写字母
bool isMark()判断字符是否为记号
bool isNonCharacter()判断字符是否为非文字字符
bool isNull()判断字符编码是否为 0x0000,也就是“\0”
bool isNumber()判断字符是否为一个数,表示数的字符不仅包括数字 0~9,还包括数字符号①、②等
bool isPrint()判断字符是否为可打印字符
bool isPunct()判断字符是否为标点符号
bool isSpace()判断字符是否为分隔符号,分隔符号包括空格、制表符
bool isSymbol()判断字符是否为符号,如特殊符号★ 、▲
char toLatin1()返回与 QChar 字符等效的 Latin1 字符,如果无等效字符则返回 0
QChar toLower()返回字符的小写形式字符,如果字符不是字母,则返回其本身
QChar toUpper()返回字符的大写形式字符,如果字符不是字母,则返回其本身
char16_t unicode()返回字符的 16 位 Unicode 编码数值

2.QChar 字符与 Latin1 字符的转换

QChar 的函数 toLatin1() 用于将 QChar 字符转换为 Latin1 字符,也就是将 UTF-16 编码的字符转换为 1 字节 Latin1 编码的字符。只有当 QChar 字符的编码为 0~255 时,函数 toLatin1() 的转换才有意义。

QChar 还有一个静态函数 QChar::fromLatin1(), 它用于将 Latin1 字符转换为 QChar 字符, 其函数原型定义如下:

QChar QChar::fromLatin1(char c)

QChar 有一个构造函数与这个静态函数功能相同,这个构造函数定义如下:

QChar::QChar(char ch)

例如,运行下面的一段代码后,字符串 str 的内容会由“Dimple”变成“Pimple”

QString str= "Dimple"; 
QChar chP= QChar::fromLatin1('P'); //使用静态函数
//QChar chP= QChar('P'); //使用构造函数
str[0]= chP; //替换了 str 中的第一个字符

3.QChar 字符的 Unicode 编码

QChar 字符是 UTF-16 编码的字符,QChar 的接口函数 unicode()用于返回字符的 UTF-16 编码, 也就是 char16_t 类型的数。我们可以通过这个函数获取任何一个字符的 UTF-16 编码,例如一个汉字的 UTF-16 编码。也可以通过 char16_t 类型的编码构造 QChar 字符,静态函数 QChar::fromUcs2() 可以实现这样的功能,其函数原型定义如下:

QChar QChar::fromUcs2(char16_t c) 

QChar 有一个构造函数与这个静态函数功能相同,这个构造函数定义如下:

QChar::QChar(char16_t ch) 

例如,运行下面的一段代码后,字符串 str 的内容由“Hello,北京”变为了“Hello,青岛”。

QString str= "Hello,北京"; 
str[6]= QChar(0x9752); //'青',使用构造函数
str[7]= QChar::fromUcs2(0x5C9B); //'岛',使用静态函数

注意,如果字符的 UTF-16 编码超过了 Latin1 编码的范围,也就是超过了 255,就不能直接传递字符用于构造 QChar 对象。例如,不能将替换 str[6]的代码写成下面的语句:

str[6]= QChar('青'); //错误的代码

虽然这行代码编译没有错误,但是程序运行结果错误,得到的结果不是期望的字符串。这是因为 Qt 的源程序文件采用的是 UTF-8 编码,源代码中的“青”是 2 字节 UTF-8 编码,而 QChar 没有这种类型参数的构造函数。

4.QChar 的逻辑运算符

两个 QChar 对象的逻辑比较就 是两个 QChar 字符的 UTF-16 编码大小的比较。例如,运行下面的一段代码后,字符串 str 中的汉 字“河”会被替换为“湖”。这里用到了 QChar 与 UTF-16 编码的转换,还用到了 QChar 的逻辑判断运算符。

QString HuStr= "河 to 湖"; //临时字符串,用于获取两个汉字的 Unicode 编码
QChar He= QChar::fromUcs2(HuStr[0].unicode());//获取'河'的 UTF-16 编码,再构造 QChar 字符
QChar Hu= QChar(HuStr[3].unicode()); //获取'湖'的 UTF-16 编码,再构造 QChar 字符
QString str= "他们来自于河南或河北"; 
for(int i=0; i<str.size(); i++) 
{ 
 if (str.at(i) == He) //如果是'河' 
 str[i]=Hu; //替换为'湖' 
} 

三. QString 字符串常用操作

1.字符串拼接

使用加号运算符可以直接将两个 QString 字符串拼接为一个字符串。

QString str1= "洋洋", str2= "得意"; 
QString str3= str1 + str2; //str3 ="洋洋得意" 
str1= str2 + str1; //str1 ="得意洋洋" 

函数 append()在当前字符串的后面添加字符串,函数 prepend()在当前字符串的前面添加字符串。

QString str1= "卖", str2= "拐"; 
QString str3= str1; 
str1.append(str2); //str1 ="卖拐" 
str3.prepend(str2); //str3 ="拐卖" 

2.字符串截取

(1)函数 front()和 back()。函数 front()返回字符串中的第一个字符,相当于 at(0);函数 back() 返回字符串中的最后一个字符。

QString str1= "Hello,北京"; 
QChar ch1= str1.front(); //ch1 ='H' 
QChar ch2= str1.back(); //ch2 ='京'

(2)函数 left()和 right()。函数 left()从字符串中提取左边 n 个字符,函数 right()从字符串中提取右边 n 个字符,n 为设定参数。

QString str1= ui->lineEdit->text(); //编辑框的内容是"G:\Qt6Book\QtSamples\qw.cpp" 
QString str2= str1.left(2); //str2 ="G:" 
str2= str1.right(3); //str2 ="cpp"

(3)函数 first()和 last()。函数 first()从字符串中提取最前面的 n 个字符,函数 last()从字符串中提取最后面的 n 个字符,n 为设定参数。first()与 left()功能相同,last()与 right()功能相同,first() 和 last()是 Qt 6.0 中引入的函数,执行速度更快。

QString str1= "G:\\Qt6Book\\QtSamples\\qw.cpp"; //使用了转义字符“\\”
QString str2= str1.first(2); //str2 ="G:" 
str2= str1.last(3); //str2 ="cpp"

注意,在程序里直接输入字符串时,符号‘\’是转义字符的引导符,所以这段程序在给 str1 赋值的字符串中使用“\\”表示一个字符‘\’。如果直接从界面上的 QLineEdit 等组件中获取输入字符串,则不用关注是否存在转义字符,Qt 会自动处理。

(4)函数 mid()。函数 mid()用于返回字符串中的部分字符串,其函数原型定义如下:

QString QString::mid(qsizetype pos, qsizetype n = -1)

其中,pos 是起始位置,n 是返回字符串中的字符个数。如果不指定参数 n,就返回从 pos 开始到 末尾的字符串,如果 pos+n 超过了字符串的边界,返回的字符串就为 null。

QString str1= "G:\\Qt6Book\\QtSamples\\qw.cpp"; 
int N= str1.lastIndexOf("\\"); //获取最后一个‘\’出现的位置
QString str2= str1.mid(N+1); //str2 ="qw.cpp" 

(5)函数 sliced()。sliced()与 mid()的功能相同,也是返回字符串的片段。sliced()是 Qt 6.0中引入的函数,它有两种不同的参数形式,其函数原型定义如下:

QString QString::sliced(qsizetype pos, qsizetype n) //返回从位置pos开始的n个字符的字符串
QString QString::sliced(qsizetype pos) //返回从位置 pos 开始到末尾的字符串

在函数 sliced()中,如果设置的参数会导致超出字符串的边界,则函数的行为是不确定的,但如果是在边界内,则 sliced()的执行速度比 mid()的快。

QString str1= "G:\\Qt6Book\\QtSamples\\qw.cpp"; 
int N= str1.lastIndexOf("\\"); //获取最后一个‘\’出现的位置
QString str2= str1.sliced(N+1); //str2 ="qw.cpp" 
str2= str1.sliced(N+1, 2); //str2 ="qw"

(6)函数 section()。函数 section()的原型定义如下:

QString QString::section(const QString &sep, qsizetype start, qsizetype end = -1, 
 QString::SectionFlags flags = SectionDefault) 

其功能是从字符串中提取以 sep 作为分隔符,从 start 段到 end 段的字符串,例如:

QString str2, str1= "学生姓名,男,2003-6-15,汉族,山东"; 
str2= str1.section(",",0,0); //str2 ="学生姓名",第一段的编号为 0 
str2= str1.section(",",1,1); //str2 ="男" 
str2= str1.section(",",0,1); //str2 ="学生姓名,男" 
str2= str1.section(",",4,4); //str2 ="山东" 

3.存储相关的函数

(1)函数 isNull()和 isEmpty()。这两个函数都会判断字符串是否为空,但是稍有差别。如果是一个空字符串,也就是只有“\0”,则 isNull()返回 false,而 isEmpty()返回 true。只有未被赋值时, isNull()才返回 true。

QString str1, str2=""; 
bool N= str1.isNull(); //N =true,未赋值
N= str2.isNull(); //N =false,已被赋值,不为 null 
N= str1.isEmpty(); //N =true 
N= str2.isEmpty(); //N =true

QString 只要被赋值了,就会在字符串的末尾自动加上“\0”。所以, 如果只是要判断字符串内容是否为空,应该使用函数 isEmpty()。

(2)函数 count()、size()和 length()。函数 size()和 length()都返回字符串中的字符个数,它们的功能相同。不带有任何参数的函数 count()与这两个函数功能相同,此外,count()还有带参数的形式,可统计某个字符串在当前字符串中出现的次数。

QString str1= "NI 好"; 
int N= str1.count(); //N =3 
N= str1.size(); //N =3 
N= str1.length(); //N =3 

(3)函数 clear()。函数 clear()清空当前字符串,使字符串为 null。

QString str1=""; 
bool N= str1.isNull(); //N =false,字符串已被赋值,不为 null 
N= str1.isEmpty(); //N =true,字符串内容为空
str1.clear(); 
N= str1.isNull(); //N =true,运行 clear()后,字符串变为 null 

(4)函数 resize()。函数 resize()改变字符串长度,该函数的一种函数原型定义如下:

void QString::resize(qsizetype size);

如果参数 size 大于字符串当前长度,就扩充字符串,但新增的字符是不确定的;如果参数 size 小于字符串当前长度,字符串会缩短为 size 个字符,多余的字符丢失。 函数 resize()还有另一种参数形式,即可以用一个字符填充字符串中扩充的位置,其原型定义如下:

void QString::resize(qsizetype size, QChar fillChar);

函数 resize()可用于预分配字符串的长度,也可以在字符串内容初始化时用给定的字符进行填充: 

QString str1; 
bool chk= str1.isNull(); //chk =true 
str1.resize(5,'0'); //str1 ="00000" 

(5)函数 fill()。函数 fill() 将字符串中的每个字符都用一个新字符替换,且可以改变字符串长度,函数原型定义如下:

QString &QString::fill(QChar ch, qsizetype size = -1);

其中,ch 是要设置的字符,size 是设置的字符串新的长度,如果不设置 size 参数的值,表示保持字符串长度不变。

QString str1= "Hello"; 
str1.fill('X'); //str1 ="XXXXX" 
str1.fill('A',2); //str1 ="AA" 
str1.fill(QChar(0x54C8),3); //str1 ="哈哈哈",0x54C8 是'哈'的 UTF-16 编码

注意,在传递某个字符构造 QChar 对象时, 对于 ASCII 字符可以直接使用字符, 但是对于汉字不能直接使用字符,而要用汉字的 Unicode 编码构造 QChar 对象。

4.搜索和判断

(1)函数 indexOf()和 lastIndexOf()

函数 indexOf() 的功能是在当前字符串内查找某个字符串首次出现的位置,其函数原型定义如下:

qsizetype QString::indexOf(const QString &str, qsizetype from = 0, 
 Qt::CaseSensitivity cs = Qt::CaseSensitive) 

参数 str 是要查找的字符串,参数 from 是开始查找的位置,参数 cs 指定是否区分大小写。参数 cs 的取值 Qt::CaseInsensitive 表示不区分大小写,取值 Qt::CaseSensitive 表示区分大小写。

函数 lastIndexOf()的功能则是在当前字符串内查找某个字符串最后出现的位置。

QString str1= "G:\\Qt6Book\\QtSamples\\qw.cpp"; 
int N= str1.indexOf("Qt"); //N =3 
N= str1.lastIndexOf("\\"); //N =20 

(2)函数 contains()

函数 contains()判断当前字符串是否包含某个字符串,可指定是否区分大小写。

QString str1= "G:\\Qt6Book\\QtSamples\\qw.cpp"; 
bool N= str1.contains(".cpp"); //N =true,默认区分大小写
N= str1.contains(".CPP"); //N =false,默认区分大小写
N= str1.contains(".CPP", Qt::CaseInsensitive); //N =true,不区分大小写

(3)函数endsWith()和startsWith()

函数startsWith()判断是否以某个字符串开头,函数endsWith() 判断是否以某个字符串结束。

QString str1= "G:\\Qt6Book\\QtSamples\\qw.cpp"; 
bool N= str1.endsWith(".CPP", Qt::CaseInsensitive); //N =true,不区分大小写
N= str1.endsWith(".CPP", Qt::CaseSensitive); //N =false,区分大小写
N= str1.startsWith("g:"); //N =false,默认区分大小写

(4)函数 count()。

带有参数的 count()统计当前字符串中某个字符串出现的次数,可以设置是否区分大小写。

QString str1= "G:\\Qt6Book\\QtSamples\\qw.cpp"; 
bool N= str1.count("Qt"); //N =2,默认区分大小写 
N= str1.count("QT"); //N =0,默认区分大小写
N= str1.count("QT", Qt::CaseInsensitive); //N =2,不区分大小写

5.字符串转换和修改

(1)函数 toUpper()和 toLower()

函数 toUpper()将字符串内的字母全部转换为大写字母, toLower()将字符串内的字母全部转换为小写字母。

QString str1= "Hello, World", str2; 
str2= str1.toUpper(); //str2 ="HELLO, WORLD" 
str2= str1.toLower(); //str2 ="hello, world" 

(2)函数 trimmed()和 simplified()

函数 trimmed()会去掉字符串首尾的空格,函数 simplified() 不仅会去掉字符串首尾的空格,还会将中间连续的空格用单个空格替换。

QString str1= " Are you OK? ", str2; 
str2= str1.trimmed(); //str2 ="Are you OK?" 
str2= str1.simplified(); //str2 ="Are you OK?"

(3)函数 chop()

函数 chop()去掉字符串末尾的 n 个字符, n 是输入参数。如果 n大于或等于字符串实际长度, 字符串内容就变为空。

QString str1= "widget.cpp"; 
str1.chop(4); //str1 ="widget",去掉了最后 4 个字符

(4)函数 insert()

函数 insert()在字符串中的某个位置插入一个字符串,它修改当前字符串的内容, 并返回字符串对象的引用。函数 insert()的一种原型定义如下:

QString &QString::insert(qsizetype pos, const QString &str)

参数 pos 表示需要插入的位置,如果 pos 大于字符串长度,字符串会自动补空格扩充长度。

QString str1= "It is great"; 
int N= str1.lastIndexOf(" "); //最后一个空格的位置
str1.insert(N, "n’t"); //str1 ="It isn't great" 

(5)函数 replace()

函数 replace()的一种原型定义如下:

QString &QString::replace(qsizetype pos, qsizetype n, const QString &after) 

 其功能是从字符串的 pos 位置开始替换 n 个字符, 替换后的字符串是 after。该函数会修改当前字 符串的内容,并返回字符串对象的引用。替换后的字符串 after 的长度可以小于 n 或大于 n, 例如:

QString str1= "It is great"; 
int N= str1.lastIndexOf(" "); //最后一个空格的位置
QString subStr= "wonderful"; 
str1.replace(N+1, subStr.size(), subStr); //str1 ="It is wonderful" 
str1.replace(N+1, subStr.size(), "OK!"); //str1 ="It is OK!" 

函数 replace()还有另一种参数形式, 即可以替换字符串中所有特定的字符,其函数原型定义如下:

QString &QString::replace(QChar before, QChar after, 
 Qt::CaseSensitivity cs = Qt::CaseSensitive) 

其功能是将字符串中的所有字符 before 替换为字符 after,可以设置是否区分大小写,例如:

QString str1= "Goooogle"; 
str1.replace('o', 'e'); 

(6)函数 remove()

其功能是从字符串的 pos 位置开始移除 n 个字符,一种原型定义如下:

QString &QString::remove(qsizetype pos, qsizetype n)

如果 n 超出了字符串的长度,就把 pos 后面的字符都移除,例如:

QString str1= "G:\\Qt6Book\\QtSamples\\qw.cpp"; 
int N= str1.lastIndexOf("\\"); 
str1.remove(N+1, 20); // str1 ="G:\Qt6Book\QtSamples\"

函数 remove()还有另一种参数形式,即可以移除字符串中某个字符出现的所有实例,例如:

QString str1= "你的,我的,他的"; 
QString DeStr= "的"; 
QChar DeChar= QChar(DeStr[0].unicode()); //获取汉字'的'的 Unicode 编码,再创建 QChar 对象
str1.remove(DeChar); //str1 ="你,我,他" 

 四. QString 字符串与数值的转换

1.字符串转换为整数

QString 有一些接口函数用于将字符串转换为整数,这几个函数的定义如下:

int toInt(bool *ok = nullptr, int base = 10) 
uint toUInt(bool *ok = nullptr, int base = 10) 
long toLong(bool *ok = nullptr, int base = 10) 
ulong toULong(bool *ok = nullptr, int base = 10) 
short toShort(bool *ok = nullptr, int base = 10) 
ushort toUShort(bool *ok = nullptr, int base = 10) 
qlonglong toLongLong(bool *ok = nullptr, int base = 10) 
qulonglong toULongLong(bool *ok = nullptr, int base = 10) 

这几个函数的输入参数都一样。变量 ok 如果不为 null, 就作为转换结果是否成功的返回变量,  false 表示转换失败, true 表示转换成功。变量 base 表示使用的进制, 默认值为 10, 也就是十进制。base 可以设置为 2~36,常用的是二进制、八进制、十六进制; base 还可以设置为 0,表示使用 C 语言的表示法,字符串以“0x”开头就是十六进制的,否则就是十进制的。

如果转换成功,这些函数的返回值是转换后的结果整数;如果转换失败,返回值是 0。如果要判断转换是否成功,不要根据返回值是否为 0 来判断,而是要传递参数 ok,根据 ok 的返回值来判断。

QString str= "153"; 
int N= str.toInt(); //默认为十进制转换,N =153 
bool ok= false; 
str= "FF"; 
N= str.toInt(&ok,16); //按十六进制转换,ok =true,N =255 
str= "10110111"; //二进制字符串
N= str.toInt(&ok,2); //按二进制转换,ok =true,N =183 
str= "0x5F"; //C 语言的十六进制字符串
N= str.toInt(&ok,0); //按 C 语言规则转换,ok =true,N =95 

2.字符串转换为浮点数

QString 有两个函数用于将字符串转换为浮点数,两个函数的原型定义如下,其中的参数 ok 用于获取返回值,表示转换是否成功。

float toFloat(bool *ok = nullptr) 
double toDouble(bool *ok = nullptr) 

3.函数 setNum()

函数 setNum()用于将整数或浮点数转换为字符串。setNum()是 overload 型函数,有很多种参数形式。将 int 类型整数转换为字符串的函数 setNum()的原型定义如下:

QString &setNum(int n, int base = 10) 

它的功能是将整数 n 转换为字符串,默认是转换为十进制字符串。如果 base 等于 16,就将整数 n 转换为十六进制字符串。

其他参数形式的函数 setNum()中,参数 n 可以是 short、uint、long 等各种整数类型。

int N= 243; 
QString str; 
str.setNum(N); //十进制, str= "243" 
str.setNum(N,16); //十六进制,str= "f3" 
str.setNum(N,2); //二进制, str= "11110011"

将浮点数转换为字符串的函数 setNum()的原型定义如下:

QString &setNum(float n, char format = 'g', int precision = 6) 
QString &setNum(double n, char format = 'g', int precision = 6) 

其中,参数 n 是待转换的浮点数,format 是格式字符,precision 表示精度位数。浮点数格式字符 的含义如下表所示,对于不同的格式字符,函数 setNum()中参数 precision 的含义不同。

浮点数格式字符的含义
格式字符格式字符的含义精度位数的含义
e科学记数法,用小写字母 e,如 2.3e+2、−2.4e−5基数的小数点后的有效位数
E科学记数法,用大写字母 E,如 2.3E+2、−2.4E−5基数的小数点后的有效位数
f自然记数法,如 123.55、−23.4303小数点后的有效位数
g使用 e 或 f,哪种简洁就用哪种小数点前后的数字位数之和
G使用 E 或 f,哪种简洁就用哪种小数点前后的数字位数之和

在下面这段程序中,函数 setNum()每种参数转换得到的字符串 str 的结果写在了注释里,从中可以看出精度位数的作用。

QString str; 
double num= 1245.2783; 
str.setNum(num,'f',5); //小数点后 5 位,str= "1245.27830" 
str.setNum(num,'E',5); //基数的小数点后 5 位,str= "1.24528E+03" 
str.setNum(num,'g',5); //整数和小数总共 5 位,str= "1245.3" 
str.setNum(num,'g',3); //整数和小数总共 3 位,str= "1.25e+03" 

4.静态函数 number()

QString 有一个静态函数 number(),其参数形式和功能与成员函数 setNum()的相似。静态函数 number()有多种参数形式,主要分为整数和浮点数两类,其函数原型定义如下:

QString QString::number(long n, int base = 10) 
QString QString::number(double n, char format = 'g', int precision = 6)

使用静态函数 QString::number()时,需要获取其返回的字符串,示例代码如下:

int N= 245; 
QString str= QString::number(203); //转换为十进制字符串,str ="245" 
str= QString::number(N,16); //转换为十六进制字符串,str ="f5" 
double num= 365.263; 
str= QString::number(num,'f',4); //小数点后 4 位,str ="365.2630" 
str= QString::number(num,'E',4); //小数点后 4 位,str ="3.6526E+02" 

5.静态函数 asprintf()

asprintf() 用于构造格式化输出各种数据的字符串,类似于标准 C 语言中的函数 printf()。函数 asprintf() 的原型定义如下:

QString QString::asprintf(const char *cformat, ...) 

其中,cformat 是格式化字符串,后面可以有任意多个变量。格式化字符串的用法与 C 语言中的 printf()的用法一样, 可以使用转义字符,也可以指定数据宽度和小数位数等。但要注意,cformat格式化字符串中支持汉字,但是替换格式化字符串中的%s 只能用 UTF-8 编码的字符串, 也就是变量的字符串中不能有汉字,否则会出现乱码。

QString str1= QString::asprintf("Year=%d,\tMonth=%2d,\tDay=%2d",2021,6,12); 
QString UPC= "UPC"; 
//QString UPC= "石油大学"; //如果这个字符串中有汉字,str2 会出现乱码
QString str2= QString::asprintf("Hello,欢迎来到 %s",UPC.toLocal8Bit().data()); 
double pi= M_PI; //圆周率常数 M_PI,在<QtMath>中定义
QString str3= QString::asprintf("Pi= %.10f",pi); //Pi= 3.1415926536 

运行这段代码后,3 个字符串的内容分别是:

Year=2021, Month= 6, Day=12 
Hello,欢迎来到 UPC 
Pi= 3.1415926536

注意,函数 asprintf()中替换%s 的只能是 char*类型的字符串,而不能是 QString 字符串。所以, 在代码中运行 UPC.toLocal8Bit().data(),就是将 QString 型变量 UPC 的 UTF-16 编码的字符串转换为本地 8 位编码的 QByteArray 型数据,再得到 QByteArray 数据的 char 类型指针。如果写成下面的代码,会出现编译警告信息,且运行时 str2 无法得到预想的字符串。

QString UPC= "UPC"; 
QString str2= QString::asprintf("Hello,欢迎来到 %s",UPC); //错误的代码,无法得到正确结果

6.函数 arg()

函数 arg()用于格式化输出各种数据的字符串, 其功能与静态函数 asprintf()的类似,使用起来更灵活。例如,运行下面的一段代码后,字符串 str1 的内容是“2021 年 08 月 03 日”。

int year=2021, month=8, day=3; 
int base= 10; //十进制
QChar ch('0'); //用于填充的字符
QString str1= QString("%1 年%2 月%3 日").arg(Y).arg(M,2,base,ch).arg(D,2,base,ch); 

字符串“%1 年%2 月%3 日”中的%1、%2、%3 是占位符,表示要用后面的函数 arg()生成的字符串替代。函数 arg() 根据输入的数据和设置输出 QString 字符串,例如对于 int 类型的输入数据, 函数 arg()的原型定义如下:

QString arg(int a, int fieldWidth = 0, int base = 10, QChar fillChar = QLatin1Char(' ')) 

其中,a 是要转换为字符串的整数;fieldWidth 是转换成的字符串占用的最少空格数;base 是转换 成的字符串显示进制, 默认是十进制; fillChar 是当 fieldWidth 大于实际数位宽度时使用的填充字符, 默认用空格。

在上面的代码中, arg(M, 2, base, ch)表示使用 2 位宽度显示变量 M 的值,使用填充字符‘0’。所以, 如果 M=8,则转换成的字符串是“08”;如果 M=12,则转换成的字符串是“12”。

格式字符串中占位符出现的顺序可以打乱,甚至可以重复出现,例如,最后一行代码如果是:

QString str1= QString("%1 年度: %3/%2/%1").arg(Y).arg(M,2,base,ch).arg(D,2,base,ch);

那么,str1 的内容为“2021 年度: 03/08/2021”。

函数 arg()还有以 QString 作为输入参数类型的,其函数原型定义如下:

QString arg(const QString &a, int fieldWidth = 0, QChar fillChar = QLatin1Char(' ')) 

变量 a 是 QString 类型,其字符串中可以有汉字。例如:

QString name= "张三"; 
int age= 25; 
QString str2= QString("他名叫%1, 今年%2 岁").arg(name).arg(age); 

运行这段代码后,字符串 str2 的内容是“他名叫张三, 今年 25 岁”。所以,使用 arg()输出代表字符串的变量时字符串中可以有汉字,而 asprintf()输出字符串变量时字符串中是不能有汉字的。

函数 arg()也可以把浮点数转换为字符串,其函数原型定义如下:

QString arg(double a, int fieldWidth = 0, char format = 'g', int precision = -1, 
 QChar fillChar = QLatin1Char(' ')) 

其中,格式字符 format 和精度位数 precision 的含义如上表所示,示例代码如下:

double pi= M_PI; //圆周率常数 M_PI,在<QtMath>中定义
int precision= 8; 
QString str3= QString("pi=%1").arg(pi,0,'f',precision); //pi=3.14159265 

运行这段代码后,字符串 str3 的内容是“pi=3.14159265”。

  • 7
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
可以先将QString类型的字符串转换成C语言的字符串,然后通过遍历字符串的每一个字符来进行分割。 具体的实现思路如下: 1. 先定义一个指针p指向字符串的首地址,然后通过while循环遍历整个字符串。 2. 判断当前字符是数字还是操作符。如果是数字,则将指针p向后移动,继续查看下一个字符;如果是操作符,则将当前位置的字符作为一个单独的字符串存储,然后将指针p向后移动。 3. 对于括号,也需要将其作为一个单独的字符串存储。需要额外判断左右括号的数量是否匹配。 4. 分割完成后,将所有的字符串存储到一个数组中,即可实现字符串的分割。 下面是示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_LEN 100 // 定义最大字符串长度 char * split(char *str, const char *delim, int *num) { char *result[MAX_LEN]; // 存储分割后的字符串 char *tmp; int count = 0; tmp = strtok(str, delim); // 分割字符串 while (tmp != NULL) { result[count++] = tmp; tmp = strtok(NULL, delim); } *num = count; // 记录分割后的字符串数量 char *ret = (char*)malloc(sizeof(char) * MAX_LEN * count); // 申请内存空间存储结果 memset(ret, 0, MAX_LEN * count); for (int i = 0; i < count; i++) { strcat(ret, result[i]); strcat(ret, " "); } return ret; // 返回分割后的字符串 } int main() { char str[MAX_LEN]; printf("Enter a string: "); scanf("%[^\n]", str); // 读取一行字符串 int len = strlen(str); int num = 0; char *delim = " ,-*()/"; // 定义分割字符集 char *result = split(str, delim, &num); printf("分割后的字符串为:\n%s\n", result); printf("分割后的字符串数量为:%d\n", num); return 0; } ``` 运行结果: ``` Enter a string: 1 + 2 * (3 - 4) / 5 分割后的字符串为: 1 + 2 * ( 3 - 4 ) / 5 分割后的字符串数量为:9 ```
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值