(十四)常用的QString函数

QString是QT中的string类,用于处理和字符串相关的事务,有意思的是QString的存储方式,用的是Unicode,16位QChar存储,可以存储汉字。

1.字符串大小

在不少博客中,可以看到博主写汉字在QString中占据一个字符,但是实际在QT5(QT5.14.2)中,汉字的字符变成了2,即和std::string的表现一致。估计是QT为了不造成误解,特意修改的,代码如下:

    QString s = "我";
    qDebug() << "QString : "<< s.size();

    std::string string1 = "我";
    qDebug() << "std::string : "<< string1.size();

在这里插入图片描述
在QT5中,汉字占据两个字符。并且size()和length()、count()表现相同。

QString test2 = "hello QT";
qDebug() << "test2 : "<< test2.size() << test2.length() << test2.count();

结果如下:

test2 :  8 8 8

2.QString字符拼接

QString除了和std::string一样,重载了+和+=运算符、有append()函数,QString还增加了arg()的方式,用于拼接各种(不限于字符串)的变量。
常用的字符拼接:

    QString s = "eeeee";
    QString res = QString("acd")+s;
    QString res1 = res.append("df");

    QString test = QString("%1 eat %2").arg("i").arg("eggs");
    qDebug() << "s : "<< s;
    qDebug() << "res : "<< res;
    qDebug() << "res1 : "<< res1;
    qDebug() << "test : "<< test;

在这里插入图片描述
(这里插句话给初学者,注意res.append(“df”)以后,打印的res值并不是预期eeeeeacd,而是把append运算以后的值加上了)

还有所有的数据类型,例如int short long等都可以拼接,类似sprintf,但是比sprintf更加灵活:

QString test = QString("%1 eat %%2 %3").arg("i").arg(50).arg("eggs");

结果如下:

test :  "i eat %50 eggs"

就是用arg()中的变量,依次去填补%1、%2、%3,最后输出一整个QString。所以推荐使用arg()而不是sprintf。

3.字符串大小写

字符串大小写转换,两个函数toUpper()和toLower()

    QString test1 = "AcGGhjK";
    QString test1_upper = test1.toUpper();
    QString test1_lower = test1.toLower();
    qDebug() << "test1_upper : "<< test1_upper;
    qDebug() << "test1_lower : "<< test1_lower;
test1_upper :  "ACGGHJK"
test1_lower :  "acgghjk"

用的比较少,一般都是在比较字符串的时候使用,但是QT进行字符串比较时,可以自定义是否需要大小写敏感。
因为我习惯用find()查找,所以会经常用,QString转成大写后、再转成std::string、在用find查找。

4.字符串截取

    QString test2 = "hello QT";
    QString test2_1 = test2.mid(6,2);//从第6个位置开始,包含第6个位置,往后2个字符,即第6和第7字符
    QString test2_2 = test2.mid(6);//从第6个位置开始,包含第6个位置,所有的字串
    qDebug() << "test2_1 : "<< test2_1;
    qDebug() << "test2_2 : "<< test2_2;

结果如下:

test2_1 :  "QT"
test2_2 :  "QT"

用的不习惯,你也可以转成std::string,用substr(),区别不大,看个人习惯,但是项目里面最好统一格式,方便阅读。

5.字符串去除空格

trimmed() 和 simplified()两个函数可以去除字符串的空格。而且实际去除空格也是用的比较多的,特别是如果你需要用户手写用户名啥的,最常见的就是用户的用户名前后加了空格
trimmed() 去掉字符串首尾的空格,用的最多。
simplified() 不仅去掉首尾的空格,中间连续的空格用一个空格替换。

QString test2 = " hello   QT ";
qDebug() << "test2_trimmed : "<< test2.trimmed();
qDebug() << "test2_simplified : "<< test2.simplified();

结果如下:

test2_trimmed :  "hello   QT"
test2_simplified :  "hello QT"

特别注意:simplified()中间连续的空格也用一个空格替换。不是去掉中间的空格,而是把连续的空格用一个空格替换!!!别用错了

6.字符串替换

如果想完全替换QString中的空格,可以使用replace(),这个函数会遍历QString中的char,替换成你想要的char。

QString test2_replace = test2.replace(" ","");//把“ ”空格替换成“”空
qDebug() << "test2_replace : "<< test2_replace;

结果如下:

test2_replace :  "helloQT"

7.字符串查找

QT的字符串查找只有两个函数indexOf () 和 lastIndexOf (),不如std::string的函数多。
indexOf ()查询第一个出现的位置,lastIndexOf ()查询最后一个出现的位置。

test2 = "hello QT";
int place = test2.indexOf("l");
int place1 = test2.lastIndexOf("l");
qDebug() << "place : "<< place;
qDebug() << "place1 : "<< place1;

结果如下:

place :  2
place1 :  3

在std::string中有更多的函数,所以一般我都会把QString转成std::string进行查找:

    test2 = "hello QT";

    qDebug() << "place2 : "<< test2.toStdString().find("l");//从左到右找l,返回的是第一个l的位置
    qDebug() << "place3 : "<< test2.toStdString().find_last_of("l");//从右到左找l,返回的是最后一个l的位置
    qDebug() << "place4 : "<< test2.toStdString().find_first_of("l");//从左到右找l,返回的是第一个l的位置
    qDebug() << "place5 : "<< test2.toStdString().find_last_not_of("T");//从右到左找l,返回的是最后一个不是T的位置,即Q的位置
    qDebug() << "place6 : "<< test2.toStdString().find_first_not_of("h");//从左到右找l,返回的是第一个不是h的位置,即e的位置
    qDebug() << "place7 : "<< test2.toStdString().rfind("l");//从右到左找l,返回的是最后一个l的位置,逆序查找

结果如下:

place2 :  2
place3 :  3
place4 :  2
place5 :  6
place6 :  1
place7 :  3

所以如果QString不涉及中文或者其他特殊字符,我一般都是转换成std::string查找。

不过QString可以指定是否大小写敏感,不过我还是不经常用,因为指定大小写敏感的参数在第三个。。。。

int lastIndexOf(const QString &s, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;

所以你要写第二个参数:从哪里查找,就是上面的from参数,如果忘记就麻烦了,CaseSensitivity敏感性是一个枚举类,大小写不敏感CaseInsensitive默认是0:

enum CaseSensitivity {
        CaseInsensitive,
        CaseSensitive
    };

例如:

    test2 = "hello QT";
    int place8 = test2.lastIndexOf("L",Qt::CaseInsensitive);
    qDebug() << "place8 : "<< place8;

我查询“l”的位置,明明指定大小写不敏感了,但是查询结果还是-1,找不到“l”。

place8 :  -1

因为我只写了两个参数,第二个参数又是枚举类,被编译器认为是0,查询的起始位置为0,所以达不到效果。所以还是少用indexOf () 和 lastIndexOf ()。除非QT在编译阶段做检查、或者更换枚举类型(等QT公司改吧)。

8.QString和std::string的相互转换

其实上面已经讲了的。
QString转std::string:

std::string test_string = test2.toStdString();

std::string转QString:

    std::string string1 = "a";
    QString string1_QString = QString::fromStdString(string1);

非常常见,请务必记住,QString和std::string经常相互转换

9.字符串包含字符

判断字符串中是否包含某个字符contains(),可以区分是否大小写敏感,比std::string要好用

    bool test2_contains = test2.contains("Qt",Qt::CaseInsensitive);
    qDebug() << "test2_contains : "<< test2_contains;

    std::string test2_string = test2.toStdString();
    bool test2_contains1 = true?false : std::string::npos != test2_string.find("Qt");
    qDebug() << "test2_contains1 : "<< test2_contains1;

结果如下:

test2_contains :  true
test2_contains1 :  false

10.字符串判空

只要讲到字符串,那就少不了判空操作,QT是isNull() 和 isEmpty()。
如果一个空字符串,只有“\0”,isNull() 返回 false,而 isEmpty() 返回 true;只有未赋值的字符串,isNull() 才返回 true。

    QString str1, str2 = "";
    bool isTrue = false;
    isTrue=str1.isNull();
    qDebug() << "isTrue1 : "<< isTrue;
    isTrue=str2.isNull();
    qDebug() << "isTrue2 : "<< isTrue;
    isTrue=str1.isEmpty();
    qDebug() << "isTrue3 : "<< isTrue;
    isTrue=str2.isEmpty();
    qDebug() << "isTrue4 : "<< isTrue;

结果如下:

isTrue1 :  true
isTrue2 :  false
isTrue3 :  true
isTrue4 :  true

这两个的选用取决于实际情况,如果需要判断字符串是否输入的为空,一般用isEmpty()就可以;如果需要判断数据库或者其它转移过来的字符串是否为空,看实际情况,isNull()较好。

11.判断字符开头或者结尾

startsWith() 判断是否以某个字符串幵头,endsWith() 判断是否以某个字符串结束。一般用在判断网址或者用户邮箱等用的较多,作为最初的判断(准确的判断还是要用正则表达式)。

    QString test3 = "https://www.baidu.com";
    QString test4 = "123456789@qq.com";
    isTrue = test3.startsWith("http://", Qt::CaseInsensitive);//判断是不是http网址,大小写不敏感
    qDebug() << "isTrue5 : "<< isTrue;
    isTrue = test4.endsWith("@qq.com", Qt::CaseInsensitive);//判断是不是qq邮箱,大小写不敏感
    qDebug() << "isTrue6 : "<< isTrue;

结果如下:

isTrue5 :  false
isTrue6 :  true

12.字符串比较

字符串比较有compare()和localeAwareCompare()。左边比右边小返回负值,等于返回0,大于返回正数

我用过compare(),它是按照Unicode的方式,即比较每个字符的ASCII码,一般情况下compare已经满足需求了。

但是如果你的工程涉及到海外语言,那么QT推荐localeAwareCompare()。注意:localeAwareCompare()是根据本地编码方式和平台来规定规则的,如果你的用户都使用Windows,那么是没问题的,如果有用macOS and iOS的,localeAwareCompare()是按照Mac系统的Order for sorted lists方式排序。

    QString test5 = "abcd";
    QString test6 = "ABCD";
    bool qstring_compare = test5.compare(test6,Qt::CaseInsensitive);
    bool qstring_localeAwareCompare = test5.localeAwareCompare(test6);
    qDebug() << "qstring_compare : "<< qstring_compare;
    qDebug() << "qstring_localeAwareCompare : "<< qstring_localeAwareCompare;

结果如下:

qstring_compare :  false
qstring_localeAwareCompare :  true

所以compare()和localeAwareCompare()两个的区别:
1.compare()根据字符的ASCII码值比较,localeAwareCompare()根据本地电脑和平台比较(如果本地是Unicode和Windows,那么和compare()没什么差别));
2.localeAwareCompare()的比较大小写敏感!!!compare()可以设置大小写不敏感。

一般compare()够用,如果你要是展示给不同国家用户“一张排序的字符表”(例如国家名),推荐localeAwareCompare()

### 配置和使用 Asio 库 要在 Qt 中集成并使用 Asio 库,可以通过设置项目的 `.pro` 文件来指定库路径以及头文件位置。以下是详细的说明: #### 设置项目配置 在 Qt 的 `.pro` 文件中,可以按照以下方式添加 Asio 和 Boost 头文件目录的位置。这使得编译器能够找到所需的头文件。 ```plaintext INCLUDEPATH += c:/asio-1.12.1/include c:/boost_1_69_0 ``` 上述命令的作用是指定 `Asio` 和 `Boost` 的头文件所在路径[^1]。通过这种方式,Qt Creator 或其他构建工具可以在编译过程中正确解析这些依赖项中的函数声明和定义。 #### 使用 Asio 进行网络编程 一旦完成配置,就可以像平常一样在代码中引入 Asio 并调用其功能。下面是一个简单的例子展示如何初始化一个异步 TCP 客户端连接: ```cpp #include <QCoreApplication> #include <iostream> #include <asio.hpp> void simple_asio_example() { try { asio::io_context io; // 创建套接字对象并与服务器建立连接 asio::ip::tcp::resolver resolver(io); asio::ip::tcp::socket socket(io); auto endpoints = resolver.resolve("example.com", "80"); asio::connect(socket, endpoints); std::cout << "Connected to example.com on port 80." << std::endl; // 发送HTTP请求数据包到远程主机 const char request[] = "GET / HTTP/1.1\r\n" "Host: example.com\r\n" "\r\n"; asio::write(socket, asio::buffer(request)); // 接收响应消息直到EOF到达为止 asio::streambuf response; asio::read_until(socket, response, "\r\n"); // 输出收到的内容至标准输出流 std::istream is(&response); std::string http_version; unsigned int status_code; std::string status_message; is >> http_version >> status_code >> std::getline(is, status_message); if (!is || http_version.substr(0, 5) != "HTTP/") { throw asio::system_error(asio::error::invalid_argument); } printf("%s %u %s\n", http_version.c_str(), status_code, status_message.c_str()); } catch (std::exception& e) { std::cerr << e.what() << std::endl; } } ``` 此示例展示了基本的客户端行为模式——创建一个TCP/IP通信信道、发送一条特定的消息给目标地址,并读取返回的数据直至结束符被检测到[^2]。 #### 注意事项 由于 Asio 是基于 C++ 实现的一个高性能 I/O 库,在实际应用开发时需要注意线程安全性和资源管理等问题。此外,如果计划部署应用程序,则还需要考虑动态链接库(DLL)或者静态链接库(LIB)的选择及其分发策略。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值