QT——QString使用帮助

QString类 简介:
编码格式:提供了一个Unicode字符字符串
存储方式:存储了一个16位QChars字符串,其中每个QChar对应一个Unicode 4.0字符
优势       :使用隐式共享(即写即复制)来减少内存使用并避免不必要的数据复制
扩展       :除了QString,Qt还提供了QByteArray类来存储原始字节和传统的8位'\0'结尾的字符串,QByteArray适用于两种主要情况是:当需要存储原始二进制数据时,以及内存保护非常重要(比喻嵌入式系统中)时


QString类 使用:

一、初始化一个字符串

方法1. 将const char*传递给他的构造函数

说明:QString使用fromUtf8()函数将const char*数据转换为Unicode,在所有接受const char*参数的QString函数中,const char* 被解释为用UTF-8编码的经典c风格“\0”结尾的字符串,常量char* 参数为0是合法的。

示例:以下代码创建了一个大小为5的QString,其中包含数据"Hello",eg:

QString str = "Hello";

 

方法2. 将字符串数组作为QChars数组

说明:QString对QChar数据进行了深度复制,因此可以修改他。如果出于性能原因,不想获取字符数据的深层副本,那么应该使用QString::fromRawData()。
示例:

  static const QChar data[4] = { 0x0055, 0x006e, 0x10e3, 0x03a3 };
  QString str(data, 4);

 

方法3. 使用resize()设置字符串的大小,并对每个字符初始化数据字符。

示例:

  QString str;
  str.resize(4);

  str[0] = QChar('U');
  str[1] = QChar('n');
  str[2] = QChar(0x10e3);
  str[3] = QChar(0x03a3);

 

方法4.  将字符串文字传递给将QString作为参数的函数,调用QString(const char*)构造函数。

 

方法5.  使用qPrintable()宏,  这个宏将给定的QString作为const char*返回,这相当于调用.tolocal8bit()  .constdata()。

二、访问字符串中的字符

方法1.  操作符[]

QString像c++数组一样使用基于0的索引。要访问位于特定索引位置的字符,可以使用运算符[]。对于非const字符串,操作符[]返回一个对字符的引用,该字符可用于赋值的左侧

 

方法2.  at()

当只读访问某个字符时,可以使用at():
优势:at()函数可以比运算符[]更快,因为它不会导致深度复制。

示例:

QString str;

  for (int i = 0; i < str.size(); ++i) {
      if (str.at(i) >= QChar('a') && str.at(i) <= QChar('f'))
          qDebug() << "Found character in range [a-f]";
  }

方法3.  使用left()、right()、mid一次提取几个字符

QString可以嵌入'\0'字符(QChar::Null)。size()函数总是返回整个字符串的大小,包括嵌入的'\0'字符。
在调用resize()函数后,新分配的字符具有未定义的值。若要将字符串中的所有字符设置为特定值,请使用fill()函数。

QString提供了数十个重载,旨在简化字符串的使用。例如,如果想讲QString与string literal进行比较,可以编写这样的代码:

QString str;

  if (str == "auto" || str == "extern"
          || str == "static" || str == "register") {
      // ...
  }

 

 

三、操作字符串数据


QString提供了以下修改字符数据的基本函数:append()、prepend()、insert()、replace()、remove()。
示例:

 QString str = "and";
  str.prepend("rock ");     // str == "rock and"
  str.append(" roll");        // str == "rock and roll"
  str.replace(5, 3, "&");   // str == "rock & roll"

1. 如果正在构建一个QString,并且余弦知道QString将包含多少个字符,那么可以调用reserve(),请求QString预先分配一定量的内存。还可以调用capacity()来查找实际分配了多少内存QString。

2. replace() 和 remove()函数,前两个参数是开始擦除的位置和应该擦除的字符数。如果想用另一个字符串替换出现的所有特定子字符串,请使用两个参数之一的replace()重载

3.从字符串中删除空白字符 ('\n', '\t', ' ', etc.)。如果希望从QString的两端删除空格,请使用trim()函数。如果希望从两端删除空格,并用字符串中的单个空格字符替换多个连续的空格,请使用simplified()。

4.如果希望查找QString中出现的所有特定字符或子字符串,请使用indexOf()或lastIndexOf()函数。前者从给定的索引位置向前搜索,后者向后搜索。两者都返回字符或子字符串的索引位置;否则,它们返回-1。例如,这里有一个典型的循环,它可以查找特定子字符串的所有出现:

  QString str = "We must be <b>bold</b>, very <b>bold</b>";
  int j = 0;

  while ((j = str.indexOf("<b>", j)) != -1) {
      qDebug() << "Found <b> tag at index position" << j;
      ++j;
  }

 

四、字符串与数字的转化

1. QString提供了许多函数提供字符串与数字的转化。请参照arg()函数、setNum()函数、number()静态函数以及toInt()、toDouble()和类似的函数

2. 要获得字符串的大小写版本,请使用toUpper()或toLower()。

3. 字符串列表由QStringList类处理。可以使用split()函数将字符串分割为字符串列表,并使用QStringList::join()将字符串列表链接为单个字符串,并使用可选的分隔符将字符串链接为

五、查询字符串数据

1. 如果您想查看QString是否以特定的子字符串开始或结束,请使用startsWith()或endsWith()
2. 如果您只想检查QString是否包含特定的字符或子字符串,请使用contains()函数。
3. 如果您想知道一个特定的字符或子字符串在字符串中出现了多少次,请使用count()

比较: qstring可以使用重载操作符进行比较,例如操作符<()、操作符<=()、操作符==()、操作符>=()等等。注意,比较只基于字符的数值Unicode值。它是非常快的,但不是人们所期望的;

排序: QString::localeAwareCompare()函数是对用户接口字符串进行排序的更好选择。

要获得指向实际字符数据的指针,请调用data()或constData()。这些函数返回指向QChar数据开头的指针。指针保证在QString上调用非const函数之前保持有效。

六、8位字符串和Unicode字符串之间的转换

QString提供了以下三个函数,它们返回字符串的const char *版本作为QByteArray:
 toUtf8()、toLatin1()和toLocal8Bit()。

1. toLatin1():返回一个Latin-1 (ISO 8859-1)编码的8位字符串。
2. toUtf8():返回一个UTF-8编码的8位字符串。UTF-8是US-ASCII (ANSI X3.4-1986)的超集,通过多字节序列支持整个Unicode字符集。
3. toLocal8Bit():使用系统的本地编码返回一个8位字符串。

为了从这些编码中进行转换,QString提供了fromLatin1()、fromUtf8()和fromLocal8Bit()QTextCodec类支持其他编码。

如上所述,QString提供了许多函数和操作符,使得与const char *和 string的互操作变得很容易。但是这个功能是一把双刃剑:如果所有字符串都是US-ASCII或Latin-1,那么QString使用起来就更方便了,但是使用错误的8位编码进行隐式的const char *转换总是有风险的。为了最小化这些风险,您可以通过定义以下两个预处理符号来关闭这些隐式转换:

QT_NO_CAST_FROM_ASCII:阻止C字符串的自动转换和指向Unicode的指针。
qt_limitted_cast_from_ascii:允许从C字符和字符数组自动转换,但禁用从字符指针到Unicode的自动转换。
QT_NO_CAST_TO_ASCII:禁用从QString到C字符串的自动转换。

为应用程序全局定义这些预处理器符号的一种方法是将以下条目添加到qmake项目文件中:

  DEFINES += QT_NO_CAST_FROM_ASCII \
             QT_NO_CAST_TO_ASCII

然后,您需要显式地调用fromUtf8()、fromLatin1()或fromLocal8Bit()来从8位字符串构造QString,或者使用轻量级的QLatin1String类,例如:

QString url = QLatin1String("http://www.unicode.org/");

类似地,必须显式调用toLatin1()、toUtf8()或toLocal8Bit()来将QString转换为8位字符串。(QTextCodec类支持其他编码。)

七、C程序员注意事项

由于c++的类型系统和QString是隐式共享的事实,QString可能被视为int或其他基本类型。例如:
结果变量是在堆栈上分配的一个普通变量。当调用return时,由于我们是按值返回,因此调用了copy构造函数并返回了字符串的副本。由于隐式共享,没有实际的复制发生。

八、Null 和 Empty 之间的区别

由于历史原因,QString区分了 null string 和 empty string。
null string:是使用QString的默认构造函数或通过将(const char *)0传递给构造函数来初始化的字符串。
empty string :是任何大小为0的字符串。
null string总是空的,但是empty string不一定是空的:

  QString().isNull();               // returns true
  QString().isEmpty();              // returns true

  QString("").isNull();             // returns false
  QString("").isEmpty();            // returns true

  QString("abc").isNull();          // returns false
  QString("abc").isEmpty();         // returns false

 

除isNull()之外的所有函数都将 null strings视为 empty strings。例如,toUtf8(). constdata()为null string返回一个指向'\0'字符的指针(不是空指针)。
QString()与QString("")比较。建议您始终使用isEmpty()函数,并避免使用isNull()函数。


更高效的String结构
许多字符串在编译时已知。但是普通的构造函数QString(“Hello”)将复制字符串的内容,将内容视为Latin-1。为了避免这种情况,可以使用QStringLiteral宏在编译时直接创建所需的数据。然后,从文本中构造QString不会在运行时造成任何开销。

稍微低效的方法是使用QLatin1String。这个类包装了一个C字符串文字,在编译时预计算它的长度,然后可以用来更快地比较qstring和转换到qstring比普通的C字符串文字。
使用QString '+'运算符,很容易从多个子字符串构造复杂字符串。您通常会这样编写代码:

      QString foo;
      QString type = "long";

      foo->setText(QLatin1String("vector<") + type + QLatin1String(">::iterator"));

      if (foo.startsWith("(" + type + ") 0x"))
          ...

这些字符串结构没有任何问题,但是有一些隐藏的低效之处。从Qt 4.6开始,可以消除它们。
首先,“+”运算符的多次使用通常意味着多次内存分配。当连接n个子字符串(其中n > 2)时,对内存分配器的调用可能多达n - 1次。

在4.6中,添加了一个内部模板类QStringBuilder以及一些辅助函数。这个类被标记为内部类,不会出现在文档中,因为您不打算在代码中实例化它。它的使用将是自动的,如下所述。这个类可以在src/corelib/tools/qstringbuilder中找到。如果你想看一看cpp的话。

QStringBuilder使用表达式模板并重新实现“%”操作符,这样当您使用“%”而不是“+”进行字符串连接时,多个子字符串连接将被延迟,直到最终结果将分配给QString为止。至此,最终结果所需的内存数量已经知道了。然后调用内存分配器一次以获得所需的空间,然后将子字符串逐个复制到其中。

内联和减少引用计数(从QStringBuilder创建的QString的ref计数通常为1,而QString::append()需要额外的测试)可以提高效率。

有三种方法可以访问这种改进的字符串构造方法。最简单的方法是在你想使用的任何地方包括QStringBuilder,并在连接字符串时使用'%'运算符而不是'+':

      #include <QStringBuilder>

      QString hello("hello");
      QStringRef el(&hello, 2, 3);
      QLatin1String world("world");
      QString message =  hello % el % world % QChar('!');

 

一个更全面的方法,是最方便的,但不是完全源代码兼容,是在您的.pro文件中定义:

DEFINES *= QT_USE_QSTRINGBUILDER

猜你喜欢

转载自blog.csdn.net/Jecklin_online/article/details/82627029