【零基礎學QT】【035】Qt中文讀寫和打印亂碼處理

爲什麼Qt和很多軟件都會有亂碼問題

  • 首先,字符串不管是存儲到文件還是內存裏面,它都只是字節而已,字符字形只是經過轉換顯示給人看的。同樣的字節,在不同的編碼下,就代表不同的字符。因此,程序寫入文件和讀取文件時,使用的編碼必須一致
  • 代碼編輯器(IDE)在保存和編譯源代碼時,也是需要知道編碼方式的,如果代碼保存時使用的編碼,和編譯器讀取代碼時使用的編碼不一樣,也會出現亂碼問題。這個道理和上面其實是一樣的,編譯器本身也是一種程序,代碼就是它讀取的文件
  • 編輯器顯示代碼和保存代碼時使用的編碼可能是不一致的。比如我們指定了IDE的編碼方式爲ASCII,是不支持中文的,但有可能我們仍然可以輸入漢字。因爲編譯器可能會用Unicode來顯示,然後保存的時候,以ASCII來存儲。當我們保存後再重啓IDE,文件就亂碼了。
  • 代碼編輯器和代碼控制檯,也有可能使用的是不同的編碼。因爲代碼編輯器管理的是文件,代碼控制檯是和cmd進行通信,其實是兩種功能
  • 切換編碼後,英文和數字不一定會亂碼。這是因爲英文字母和羅馬數字屬於國際通用字符,幾乎所有的編碼格式都包含這些字符,並且和ASCII使用一樣的編碼值。所以即便切換了編碼,它們有可能還是表示同樣的字符
  • std::string是以char數組的形式來存儲字符的,一個字符佔一個字節,而漢字屬於寬字符,一個字符佔兩個字節,因此需要通過轉換才能正常打印顯示。QDebug和QString自動幫我們封裝實現了這些功能,用C++原生代碼轉換過於麻煩,建議用Qt現成的接口
  • 關於不同編碼方式的區別,可以參考這篇博客:https://hellogoogle.blog.csdn.net/article/details/103455674

理想的文件讀寫方式


	//打印源代碼字符串
	//編譯器統一使用默認編碼,或IDE自動識別源文件編碼,無需指定
	string str = "hello";
	print(str);

	//寫入文件
	//指定字符編碼,或省略編碼參數,使用默認編碼
	file.write(byte[] buffer, string encoding);
	file.write(string text, string encoding);
	
	//讀取文件
	//指定字符編碼,或省略編碼參數,使用默認編碼
	file.setEncoding(string encoding);
	string line= file.readLine();
	string text = file.readAll();

這是一個比較理想,也很容易理解的代碼形式。如果字符串可以這樣讀寫,string也可以直接打印,那真是太爽了
在很多Java代碼中,字符串的讀寫就是如此簡單。因爲代碼編輯器和開發框架,都默認使用了UTF8編碼,保證了一致性問題
如果不指定編碼,那麼所有地方默認使用的都是UTF8編碼,這樣在寫代碼時,甚至都可以省略編碼方式這個參數了
只不過很遺憾,C++畢竟是底層語言(低級語言),封裝程度較低,沒有一個正式易用的string類型,std::string本質上還是一個char數組,或者說是字節數組,沒有字符編碼信息。
在做Qt開發時,還是建議所有地方都使用Qt的QString,比較Qt對編碼功能進行了封裝,當然Qt沒有像某些Java框架那樣實現完全自動化,還需要我們自己去了解如何使用接口,不過比起原生C++代碼,已經算是極其方便了

Qt可以防止中文亂碼的一些編碼習慣

  • 設置QtCreator代碼編輯器編碼爲UTF8
    【Tools】-【Options】-【Text Editor】-【Behavior】-【Default Encoding】-【UTF-8】
  • 告訴編譯器代碼文件的編碼方式。編譯器是不知道IDE代碼文件編碼方式的,在未明確指定IDE編碼方式的情況下,將使用編譯器默認的編碼方式,而MSVC編譯器和MinGW編譯器的默認編碼方式是不一樣,這樣就有可能出問題。在未明確指定編碼方式的情況下,最終代碼是否正確,既取決於文件編碼方式,又取決於編譯器默認編碼方式,就算允許正常,有可能只是偶然,換個編譯器可能就亂碼了
  • 讀寫時設置文本流的編碼爲UTF8
  • 打印文本時使用QDebug和QString

	//指定源文件編碼方式
	QTextCodec::setCodecForCStrings(QTextCodec::codecForName("utf-8"));

    //寫文本
    QTextStream out(&file);
    out.setCodec("utf-8");
    out << QString("C++入門到放棄") << endl;

    //讀文本
    QTextStream in(&file);
    QString text;
    in.setCodec("utf-8");
    in >> text >> endl;

    //打印文本
    qDebug() << QString("C++入門到放棄") << endl;

QTextCodec::setCodecForCStrings相當於全局設置,如果我們想不同的字符保存爲不同的編碼格式,也可以使用以下接口

	
	//視str爲ASCII編碼
	QString QString::fromAscii ( const char * str, int size = -1 )
	//視str爲Latin1編碼
	QString QString::fromLatin1 ( const char * str, int size = -1 ) 
	//視str爲Utf8編碼
	QString QString::fromUtf8 ( const char * str, int size = -1 )
	//視str爲本地編碼,由操作系統默認編碼決定
	QString QString::fromLocal8Bit ( const char * str, int size = -1 )

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