Qt中的 QString和QByteArray

   最近在用Qt做串口數據收發方面的實驗,經常用到像QString和QByteArray一類的字符處理類,因此在這裏做一個總結,文章有點凌亂,希望見諒。

 

      先要說的是QString。

      之所以把QString單獨拿出來,是因爲string是很常用的一個數據結構,甚至在很多語言中,比如JavaScript,都是把string作爲一種同int等一樣的基本數據結構來實現的。

      每一個GUI程序都需要string,這些string可以用在界面上的提示語,也可以用作一般的數據結構。C++語言提供了兩種字符串的實現:C風格的字符串,以'/0‘結尾;std::string,即標準模版庫中的類。Qt則提供了自己的字符串實現:QString。QString以16位Uniode進行編碼。我們平常用的ASCII等一些編碼集都作爲Unicode編碼的子集提供。關於編碼的問題,我們會到以後的時候再詳細說明。

在使用QString的時候,我們不需要擔心內存分配以及關於'/0'結尾的這些注意事項。QString會把這些問題解決。通常,你可以把QString看作是一個QChar的向量。另外,與C風格的字符串不同,QString中間是可以包含'/0'符號的,而length()函數則會返回整個字符串的長度,而不僅僅是從開始到'/0'的長度。

     同Java的String類類似,QString也重載的+和+=運算符。這兩個運算符可以把兩個字符串連接到一起,正像Java裏面的操作一樣。QString可以自動的對佔用內存空間進行擴充,這種連接操作是恨迅速的。下面是這兩個操作符的使用:

  1. QString str = "User: ";  
  2. str += userName + "/n"

QString的append()函數則提供了類似的操作,例如:

  1. str = "User: ";  
  2. str.append(userName);  
  3. str.append("/n"); 

C語言中有printf()函數作爲格式化輸出,QString則提供了一個sprintf()函數實現了相同的功能:

  1. str.sprintf("%s %.1f%%""perfect competition", 100.0); 

這句代碼將輸出:perfect competition 100.0%,同C語言的printf()一樣。不過前面我們也見到了Qt提供的另一種格式化字符串輸出的函數arg():

  1. str = QString("%1 %2 (%3s-%4s)")  
  2.       .arg("permissive").arg("society").arg(1950).arg(1970); 

這段代碼中,%1, %2, %3, %4作爲佔位符,將被後面的arg()函數中的內容依次替換,比如%1將被替換成permissive,%2將被替換成society,%3將被替換成1950,%4將被替換曾1970,最後,這句代碼輸出爲:permissive society (1950s-1970s). arg()函數比起sprintf()來是類型安全的,同時它也接受多種的數據類型作爲參數,因此建議使用arg()函數而不是傳統的sprintf()。

使用static的函數number()可以把數字轉換成字符串。例如:

  1. QString str = QString::number(54.3); 

你也可以使用非static函數setNum()來實現相同的目的:

  1. QString str;  
  2. str.setNum(54.3); 

而一系列的to函數則可以將字符串轉換成其他基本類型,例如toInt(), toDouble(), toLong()等。這些函數都接受一個bool指針作爲參數,函數結束之後將根據是否轉換成功設置爲true或者false:

  1. bool ok;  
  2. double d = str.toDouble(&ok);  
  3. if(ok)  
  4. {  
  5.     // do something...  
  6. else {  
  7.     // do something...  

對於QString,Qt提供了很多操作函數,例如,使用mid()函數截取子串:

  1. QString x = "Nine pineapples";  
  2. QString y = x.mid(5, 4);            // y == "pine"  
  3. QString z = x.mid(5);               // z == "pineapples" 

mid()函數接受兩個參數,第一個是起始位置,第二個是取串的長度。如果省略第二個參數,則會從起始位置截取到末尾。正如上面的例子顯示的那樣。

函數left()和rigt()類似,都接受一個int類型的參數n,都是對字符串進行截取。不同之處在於,left()函數從左側截取n個字符,而right()從右側開始截取。下面是left()的例子:

  1. QString x = "Pineapple";  
  2. QString y = x.left(4);      // y == "Pine" 

函數indexOf()返回字符串的位置,如:

  1. QString x = "sticky question";  
  2. QString y = "sti";  
  3. x.indexOf(y);               // returns 0  
  4. x.indexOf(y, 1);            // returns 10  
  5. x.indexOf(y, 10);           // returns 10  
  6. x.indexOf(y, 11);           // returns -1 

函數startsWith()和endsWith()可以檢測字符串是不是以某個特定的串開始或結尾,例如:

  1. if (url.startsWith("http:") && url.endsWith(".png"))  
  2. {  

這段代碼等價於

  1. if (url.left(5) == "http:" && url.right(4) == ".png")  
  2. {  

不過,前者要比後者更加清楚簡潔,並且性能也更快一些。

QString還提供了replace()函數供實現字符串的替換功能;trimmed()函數去除字符串兩側的空白字符(注意,空白字符包括空格、Tab以及換行符,而不僅僅是空格);toLower()和toUpper()函數會將字符串轉換成小寫大寫字符串;remove()和insert()函數提供了刪除和插入字符串的能力;simplified()函數可以將串中的所有連續的空白字符替換成一個,並且把兩端的空白字符去除,例如"   /t   ”會返回一個空格" "。

將const char *類型的C風格字符串轉換成QString也是很常見的需求,簡單來說,QString的+=即可完成這個功能:

  1. str += " (1870)"

這裏,我們將const char * 類型的字符串" (1870)"轉換成爲QString類型。如果需要顯式的轉換,可以使用QString的強制轉換操作,或者是使用函數fromAscii()等。爲了將QString類型轉成const char *字符串,需要進行兩步操作,一是使用toAscii()獲得一個QByteArray類型對象,然後調用它的data()或者constData()函數,例如:

  1. printf("User: %s/n", str.toAscii().data()); 

爲了方便使用,Qt提供了一個宏qPrintable(),這個宏等價於toAscii().constData(),例如:

  1. printf("User: %s/n", qPrintable(str)); 

我們調用QByteArray類上面的data()或者constData()函數,將獲得QByteArray內部的一個const char*類型的字符串,因此,我們不需要擔心內存泄漏等的問題,Qt會替我們管理好內存。不過這也暗示我們,注意不要使用這個指針太長時間,因爲如果QByteArray被delete,那麼這個指針也就成爲野指針了。如果這個QByteArray對象沒有被放在一個變量中,那麼當語句結束後,QbyteArray對象就會被delete,這個指針也就被delete 了。

 

接下來說說QString和QByteArray之間的轉換,這裏說兩種,都是從網上搜到的。

 

第一種,數據流的方式,這裏只說從QByteArray轉向QString。

QByteArray encodedString = "xxx";
QTextCodec *codec = QTextCodec::codecForName("KOI8-R");
QString string = codec->toUnicode(encodedString);

第二種,常用的,網上看到的。

 

//常用參數類型:char *字符串, QByteArray字符數組, QString字符串
//需要轉換:char * ---轉---  QByteArray  ---需要調用QByteArray類的構造函數
char*     --------------QByteArray(const char*)-----------> QByteArray
char* str;
QByteArray byte(str);

char*     --------------QString(const char*)-------------->QString
char* str;
QString string(str);

QByteArray   -------------data()-------------------->char*
QByteArray byte;
char* str = byte.data();

QByteArray  ------------QString()------------------->QString
QByteArray byte;
QString string(byte);

QString  --------------toAscii()--------------------> QByteArray
QString string;
QByteArray byte = string.toAscii();

QString -------------qPrintable()------------------>char*
QString string;
char* str = qPrintable(string);


發佈了12 篇原創文章 · 獲贊 1 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章