1. 程式人生 > >QT讀取中文檔案

QT讀取中文檔案

   雖然C++標準中有了檔案讀取的相關類,也很好用,但是在涉及到QT程式設計的時候卻用起來不方便了,因為QT本身很多元件都是關聯的自身的QString型別的字串,所以再用C++本身String型別的時候就不是那麼方便了,需要進行轉化,這樣給程式帶來了複雜度,同時也帶來了轉化的開銷,所以如果用QT開發,可以就用它本身所帶的這些型別進行處理,形成一個系統,便於資料在程式之中的互動和共用。
   QT很好,但是在處理中文或者其他語言的時候要注意編碼格式,如果沒有注意,讀取檔案的時候可能讀出來的就是亂碼或者乾脆程式就死掉了,這是我們所不願意看到的,下面就講講怎麼樣通過QT的類來讀取中文檔案。


介紹部分
   我們需要用到幾個標頭檔案中的類:
#include <qstring.h>
#include <qfile.h>
#include <qtextstream.h>
#include <qtextcodec.h>

QString

QString類提供了一個Unicode文字和經典的C以零結尾的字元陣列的抽象。 
QString使用隱含共享,這使它非常有效率並且很容易使用。 
所有的QString的方法都使用const char *引數,const char *被解釋為經典的C風格的以零結尾的ASCII字串。所以const char *引數為0是合法的。如果const char *不是以零結尾的,結果是不確定的。把經典的C字串複製到QString的函式將不會複製結尾的0字元。QString的QChar陣列(可以通過unicode()返回)通常不以零結尾。如果你需要把QString傳遞到一個需要C的以零結尾的字串,請使用latin1()。 
沒有分配任何東西的QString是零,也就是長度和資料指標都為0。引用空字串(“”,一個單一的'/0'字元)的QString是空。零和空這兩個QString在方法中都是合法的。把(const char *) 0賦值給QString給定了一個零QString。為了方便,QString::null是一個零QString。當排序的時候,空字串在最前面,然後是非空字串,然後才是零字串。我們建議使用if ( !str.isNull() ),而不是if ( !str )來檢測非零字串,關於解釋說明也可以參考operator!()。 
注意如果你發現你正在混合使用QCString、QString和QByteArray,這將會導致很多不必要的複製並且也許會預示著你正在處理的真實自然資料是不確定的。如果資料是以零結尾的八位資料,請使用QCString;如果它是沒有結尾的(也就是包含0)八位資料,請使用QByteArray;如果它是文字,請使用QString。 
字串列表可以使用QStringList類來處理。你可以使用QStringList::split()來把一個字串分割為一個字串列表,並且可以使用QStringList::join()把一個字串列表連線成一個使用隨意間隔符的字串。你也可以使用QStringList::grep()從一個字串列表中獲得包含特定子字串或者包含匹配特定的regex的字串列表。 
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
QFile


QFile類是一個操作檔案的輸入/輸出裝置。 
QFile是用來讀寫二進位制檔案和文字檔案的輸入/輸出裝置。QFile可以自己單獨被使用,但是如果和QDataStream或QTextStream一起使用將更加方便。 
檔名通常可以通過建構函式來傳遞,但也可以使用setName()來設定。你可以通過exists()來檢查一個檔案是否存在並且可以通過remove()來移去一個檔案。 
檔案可以用open()來開啟、用close()來關閉、用flush()來重新整理。資料通常可以使用QDataStream或者QTextStream進行讀寫,但你也可以使用readBlock()和readLine()來讀,使用writeBlock()來寫。QFile也支援getch()、 ungetch()和putch()。 
size()可以返回檔案的大小。你可以通過使用at()函式得到當前檔案位置或者移到一個新的檔案位置。如果你到了檔案的末尾,atEnd()返回真。handle()返回檔案控制代碼。 
這裡是一個使用QTextStream來一行一行地讀取一個文字檔案的程式碼段。它會把每一行帶上一個行號打印出來。

    QStringList lines;
    QFile file( "file.txt" );
    if ( file.open( IO_ReadOnly ) ) {
        QTextStream stream( &file );
        QString line;
        int n = 1;
        while ( !stream.eof() ) {
            line = stream.readLine(); // 不包括“/n”的一行文字
            printf( "%3d: %s/n", n++, line.latin1() );
            lines += line;
        }
        file.close();
    }
  
寫文字也很容易(假設我們有一個行的字串列表要寫):

    QFile file( "file.txt" );
    if ( file.open( IO_WriteOnly ) ) {
        QTextStream stream( &file );
        for ( QStringList::Iterator it = lines.begin(); it != lines.end(); ++it )
            stream << *it << "/n";
        file.close();
    }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////  
QTextStream

QTextStream類提供了使用QIODevice讀寫文字的基本功能。 
文字流類的功能介面和標準的C++的iostream類非常相似。iostream和QTextStream的不同點是我們的流操作在一個很容易被繼承的QIODevice上,而iostream只能操作一個不能被繼承的FILE *指標。 
Qt提供了幾個和iostream相似的全域性函式: 
bin設定QTextStream來讀/寫二進位制數字 
oct設定QTextStream來讀/寫八進位制數字 
dec設定QTextStream來讀/寫十進位制數字 
hex設定QTextStream來讀/寫十六進位制數字 
endl強制換行 
flush強制QIODevice重新整理任何被快取的資料 
ws作為任何可用的控制符(在輸入的時候) 
reset重新設定QTextStream為它的預設模式(請見reset()) 
qSetW(int)設定欄位寬度作為指定引數 
qSetFill(int)設定填充字元作為指定引數 
qSetPrecision(int)設定精確度作為指定引數 
警告:預設情況下,QTextStream在讀取流的時候,會自動地檢測流中的數字是十進位制、八進位制、十六進位制或者二進位制格式。具體情況是,一個以“0”為開頭的數字是八進位制的,比如順序為“0100”將會被解釋為64。 
QTextStream類讀寫文字,它不適合處理二進位制資料(而QDataStream是適合的)。 
預設情況下,輸出的是使用本地8位編碼後的Unicode文字(比如,QString)。這些可以使用setEncoding()方法進行改變。對於輸入,QTextStream會自動檢測標準Unicode“位元組順序標記的”文字檔案,否則會使用本地8位編碼。 
QIODevice在建構函式中被設定,或者之後在setDevice()中使用。如果輸入到達了atEnd(),返回真。資料可以使用operator>>()過載操作符讀到適當型別的變數中,或者使用read()把它作為整個部分讀到一個單一的字串中,或者使用readLine()把一次讀一行。使用skipWhiteSpace()可以忽略控制符。你可以使用flags()或setf()來設定流的標記。這個流也支援width()、precision()和 fill(),使用reset()可以重新恢復預設設定。 
也可以參考QDataStream、輸入/輸出和網路和文字相關類.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

QTextCodec

QTextCodec 類提供文字編碼之間的轉換。
QT使用Unicode來儲存,繪製以及操作字串。在很多情況下,你可能想要使用不同的編碼方式來處理資料。例如大部分的日語檔案都被儲存在Shift-JIS或者 ISO2022的檔案中,而俄羅斯的使用者常常使用KOI8-R或者CP1251編碼方式。QT提供了一個QTextCodec 類集合來從Unicode格式轉化到相應的格式。

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

程式碼部分

#include <qstring.h>
#include <qfile.h>
#include <qtextstream.h>
#include <qtextcodec.h>

int main() 
{   
 QFile file("test.txt");
 if (file.open(IO_ReadOnly|IO_Raw))
 {
  QTextStream floStream(&file);
  QString line;
  QTextCodec *codec=QTextCodec::codecForName("GBK");
  floStream.setCodec(codec);
 
  while ( floStream.atEnd()==0 ) 
  {
   line = codec->fromUnicode(floStream.readLine());
   qWarning(line);
  }
  file.close();     
 }
 return 0;
}
程式碼中的主要改動就是黃底的部分
意思就是創立一箇中文GBK編碼樣式,然後按照這種方式來把讀入的檔案流進行重新編碼,這樣中文就可以順利輸出了,不信你可以試一試,哈哈,先介紹這麼多,下次有什麼下次再寫啦。