qt5的中文亂碼問題,QString、QStringLiteral 為 UTF-16 編碼

qt5的中文亂碼問題一直沒有很明確的處理方案。

今天處理進程間通信時,也遇到了qt5亂碼問題,一邊是設置的GBK,一邊設置的是UTF8,單向通信約定采用UTF8。
發送端保證發的是UTF8字符串,因為UTF8在網絡數據包中沒有字節序問題。
問題出在發送端,字符串的原始編碼不明確,轉換方案一直靠猜,咨詢多個AI助手,也都是胡亂猜測,沒有一個能解決,沒有一個能給出確定解釋。類似于,在一個陌生環境,自己不知道自己在哪。

轉機出現在,某個AI突然說了兩句話:
QString內部是UTF-16 編碼。
QStringLiteral可以確保字符串是UTF-16 編碼。

這個關鍵信息,類似地圖中的關鍵參考點,從確定的參考點出發,每一步都確定轉換出來的數據是什么編碼,不就可以解決亂碼問題了嗎?

于是,解決方案就明確了:
發送端:

NetSendFunction(QString message=QStringLiteral("中文法文..."));
QByteArray data = message.toUtf8();

data確定是UTF8編碼,作為網絡數據包的一部分發送出去。

接收端:

QString message = QString::fromUtf8(data);

QString QStringLiteral 源碼

為了預防AI胡說誤導,稍微調查一下qt源碼:

typedef QTypedArrayData<ushort> QStringData; //數組中存的是ushort是關鍵點
class Q_CORE_EXPORT QString {
public:typedef QStringData Data;...    Data *d;//實際存儲str的地方
#define QT_UNICODE_LITERAL(str) u"" str // 關鍵點在u這個C++前綴
#define QStringLiteral(str) \([]() noexcept -> QString { \enum { Size = sizeof(QT_UNICODE_LITERAL(str))/2 - 1 }; \static const QStaticStringData<Size> qstring_literal = { \Q_STATIC_STRING_DATA_HEADER_INITIALIZER(Size), \QT_UNICODE_LITERAL(str) }; \QStringDataPtr holder = { qstring_literal.data_ptr() }; \const QString qstring_literal_temp(holder); \return qstring_literal_temp; \}()) \/**/

C++標準規定u前綴生成UTF-16,確保跨編譯器的一致性。 所以核心是c++規范起了作用,各種編譯器實現必須滿足這一結果。
這種前綴類似運算符號。 用戶也可以自定義這種前綴,它會觸發函數調用。

其它細節:
QStringLiteral,這個宏用于在編譯時創建一個QString對象,以提高運行時效率。
使用立即調用的lambda表達式,在編譯時生成靜態的QStaticStringData實例qstring_literal 。
qstring_literal_temp通過持有QStringDataPtr的臨時QString對象,直接引用靜態數據,無需動態內存分配或拷貝,提升效率。

補充deepseek給出的參考

在 Qt5 中,QString 的內部編碼始終是 UTF-16。這是 Qt 框架設計的核心特性之一,目的是統一處理 Unicode 字符。以下是詳細解釋和驗證方法:


1. QString 的內部編碼是 UTF-16

  • UTF-16 的特性
    • 每個基本字符由 16 位(即一個 QChar)表示。
    • 對于 Unicode 中超出 基本多語言平面(BMP, U+0000 到 U+FFFF) 的字符(如 Emoji 或某些漢字),Qt 會使用 代理對(Surrogate Pairs),即兩個 QChar 表示一個字符。
  • Qt 官方文檔的明確說明

    “QString stores a string of 16-bit QChars, where each QChar corresponds to one Unicode 4.0 character.”
    (摘自 Qt 5.15 文檔)


2. 為什么選擇 UTF-16?

  • 跨平臺一致性:UTF-16 能夠覆蓋絕大多數現代語言的字符,同時平衡內存占用和性能。
  • 與操作系統 API 兼容:Windows 原生 API 使用 UTF-16,Qt 選擇此編碼可以高效與之交互,避免轉換開銷。

3. 如何驗證 QString 的編碼?

方法 1:觀察字符存儲方式

通過檢查 QString 中字符的存儲長度和代理對的存在,可以間接驗證 UTF-16 編碼。例如:

QString str = u"𠮷"; // 這是一個超出 BMP 的字符(U+20BB7)
qDebug() << str.length(); // 輸出 2,因為使用了代理對
方法 2:查看內存布局

通過調試器查看 QString 的內存,可以看到每個字符占 16 位:

QString str = "Hello";
const QChar *data = str.data();
// 在調試器中查看 data 數組,每個元素為 16 位
方法 3:轉換到其他編碼

通過 toUtf8()toLatin1() 等方法的轉換行為,可以間接確認內部編碼:

QString str = u"?"; // Unicode 字符 U+00C4
qDebug() << str.toUtf8();   // 輸出 UTF-8 編碼的字節序列:0xC3 0x84
qDebug() << str.toLatin1(); // 輸出 Latin-1 編碼的字節:0xC4

4. 注意事項

  • 與源碼編碼無關QString 的內部編碼是固定的 UTF-16,與源代碼文件編碼(如 UTF-8、GBK)無關。例如:
    // 無論源碼是 UTF-8 還是 GBK,以下字符串都會被正確轉換為 UTF-16
    QString str = "你好";
    
  • 轉換函數的用途toUtf8()fromLocal8Bit() 等方法用于與外部數據(如文件、網絡)交互時進行編碼轉換,不影響 QString 內部存儲。

5. 總結

  • QString 內部編碼固定為 UTF-16,開發者無需動態判斷。
  • 若需要處理其他編碼的數據(如 UTF-8、GBK),需通過轉換方法(如 QString::fromUtf8())與 QString 交互。
  • 對于超出 BMP 的字符,Qt 會自動使用代理對,確保兼容性。

參考文檔:QString Class | Unicode in Qt

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/896665.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/896665.shtml
英文地址,請注明出處:http://en.pswp.cn/news/896665.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

解鎖瀏覽器內置API,助力跨標簽/跨頁面數據通信

1 BrodcastChanner 概念 BroadcastChannel接口表示給定源的任何瀏覽上下文都可以訂閱的命名頻道。它允許同源的不同瀏覽器窗口、標簽頁、frame 或者 iframe 下的不同文檔之間相互通信。消息通過message事件進行廣播&#xff0c;該事件在偵聽該頻道的所有BroadcastChannel對象上…

Mysql-如何理解事務?

一、事務是什么東西 有些場景中&#xff0c;某個操作需要多個sql配合完成&#xff1a; 例如&#xff1a; 李四這個月剩下的前不夠交房租了&#xff0c;找張三借1000元急用&#xff1a; &#xff08;1&#xff09;給張三的賬戶余額 減去1000元 updata 賬戶表 set money money -…

《deepseek FlashMLA :高效的 MLA 解碼內核》:此文為AI自動翻譯

FlashMLA GitHub - deepseek-ai/FlashMLA FlashMLA 是適用于 Hopper GPU 的高效 MLA 解碼內核&#xff0c;針對可變長度序列服務進行了優化。 當前發布&#xff1a; BF16、FP16塊大小為 64 的分頁 kvcache 快速開始 安裝 python setup.py install 基準 python tests/test_fl…

Windows對比MacOS

Windows對比MacOS 文章目錄 Windows對比MacOS1-環境變量1-Windows添加環境變量示例步驟 1&#xff1a;打開環境變量設置窗口步驟 2&#xff1a;添加系統環境變量 2-Mac 系統添加環境變量示例步驟 1&#xff1a;打開終端步驟 2&#xff1a;編輯環境變量配置文件步驟 3&#xff1…

藍橋杯 之 填空題-位運算與循環

文章目錄 循環握手問題門牌制作-循環小球反彈幸運數藝術與籃球跑步 位運算3個1美麗的2024 位運算 可以關注這個Lowbit(x) 如何判斷最低位是否是1&#xff1f; num&1 1就說明num最低位是1 循環 循環 握手問題 握手問題 思路分析&#xff1a; 可以直接計算出來&#xff…

Java進階——反射機制超全詳解

反射能在運行時動態操作類和對象的能力&#xff0c;極大地增強了程序的靈活性。但是反射的使用也伴隨著性能開銷和安全風險。本文將由博主帶你一起深入探討 Java 反射的核心概念、關鍵類和方法&#xff0c;以及在日常開發中的應用場景。 本文目錄 一、反射的核心概念1. 運行時類…

OAK相機的抗震性測試

在工業環境中&#xff0c;雙目視覺相機必須具備與工作環境同等的堅固性。鑒于部分客戶會將我們的相機應用于惡劣環境&#xff08;例如安裝在重型機械上&#xff09;&#xff0c;我們依據EN 60068-2-6:2008標準對相機進行了振動耐受性測試。 測試涉及的相機型號包括&#xff1a…

Express MVC

1. 安裝依賴 npm init -y npm install express npm install --save-dev typescript ts-node ejs types/node types/express tsc --init 2. 項目目錄結構如下&#xff0c;沒有的手動創建 /my-app/src/modelsuser.ts/viewsindex.ejsuserList.ejs/controllersuserController.ts…

apache-maven-3.2.1

MAVEN_HOME D:\apache-maven-3.2.1 PATH D:\apache-maven-3.2.1\bin cmd mvn -v <localRepository>d:\localRepository</localRepository> setting.xml <?xml version"1.0" encoding"UTF-8"?><!-- Licensed to the Apache Soft…

合并兩個有序鏈表:遞歸與迭代的實現分析

合并兩個有序鏈表&#xff1a;遞歸與迭代的實現分析 在算法與數據結構的世界里&#xff0c;鏈表作為一種基本的數據結構&#xff0c;經常被用來解決各種問題。特別是對于有序鏈表的合并&#xff0c;既是經典面試題&#xff0c;也是提高編程能力的重要練習之一。合并兩個有序鏈…

破解密碼防線:滲透測試中的密碼攻擊手法匯總

密碼是網絡安全中的一道重要防線&#xff0c;然而&#xff0c;若密碼策略不嚴密&#xff0c;往往會為攻擊者提供可乘之機。本文將簡要介紹滲透測試中關于密碼的幾種常見攻擊思路和手法。 1. 確認使用默認及常見的賬號密碼 在滲透測試的初期&#xff0c;攻擊者通常會嘗試使用系…

CSS Selectors

當然&#xff0c;理解純CSS選擇器&#xff08;CSS Selectors&#xff09;對于進行UI自動化測試非常重要。CSS選擇器允許您通過元素的屬性、層級關系、類名、ID等來精準定位頁面上的元素。下面我將詳細講解CSS選擇器的常見用法&#xff0c;并結合您的需求提供具體的示例。 1. 基…

【java】@Transactional導致@DS注解切換數據源失效

最近業務中出現了多商戶多租戶的邏輯&#xff0c;所以需要分庫&#xff0c;項目框架使用了mybatisplus所以我們自然而然的選擇了同是baomidou開發的dynamic.datasource來實現多數據源的切換。在使用初期程序運行都很好&#xff0c;但之后發現在調用com.baomidou.mybatisplus.ex…

淺入淺出Selenium DevTools

前言 在自動化測試領域&#xff0c;Selenium一直是主流工具之一。隨著前端技術的不斷發展&#xff0c;瀏覽器的功能也在不斷豐富。 Selenium 3版本前&#xff0c;一套通用的采集流程如上圖所示&#xff1a; 打開Charles&#xff0c;設置Session自動導出頻次及導出路徑Seleniu…

04 路由表的IP分組傳輸過程

目錄 1、路由表的核心結構 2、IP分組傳輸過程和數據包轉發過程 2.1、IP分組傳輸過程 2.2、數據包轉發過程 2.3、IP分組傳輸過程和數據包轉發的區別 3、數據包的變化 3.1、拓撲結構 3.2、傳輸過程詳解&#xff08;主機A → 主機B&#xff09; 3.2.1、主機A發送數據 3.2…

【子網掩碼計算器:Python + Tkinter 實現】

子網掩碼計算器&#xff1a;Python Tkinter 實現 引言代碼功能概述代碼實現思路1. 界面設計2. 功能實現3. 事件處理 子網掩碼計算器實現步驟1. 導入必要的庫2. 定義主窗口類 SubnetCalculatorApp3. 創建菜單欄4. 創建界面組件5. 判斷 IP 地址類別6. 計算子網信息7. 其他功能函…

【練習】【貪心】力扣1005. K 次取反后最大化的數組和

題目 1005 K 次取反后最大化的數組和 給你一個整數數組 nums 和一個整數 k &#xff0c;按以下方法修改該數組&#xff1a; 選擇某個下標 i 并將 nums[i] 替換為 -nums[i] 。 重復這個過程恰好 k 次。可以多次選擇同一個下標 i 。 以這種方式修改數組后&#xff0c;返回數組 可…

3dsmax中使用python創建PBR材質并掛接貼圖

前言 筆者處理模型時下載到一個pbr材質庫貼圖包&#xff0c;手動每次創建材質過于麻煩&#xff0c;因此計劃使用自動化腳本根據貼圖名自動創建材質。 3dsmax的原本腳本使用的是maxscript&#xff0c;語法有點奇怪懶得學&#xff0c;發現也支持使用python編寫腳本&#…

Metal學習筆記九:光照基礎

光和陰影是使場景流行的重要要求。通過一些著色器藝術&#xff0c;您可以突出重要的對象、描述天氣和一天中的時間并設置場景的氣氛。即使您的場景由卡通對象組成&#xff0c;如果您沒有正確地照亮它們&#xff0c;場景也會變得平淡無奇。 最簡單的光照方法之一是 Phong 反射模…

JAVA學習筆記038——bean的概念和常見注解標注

什么是bean? Bean 就是 被 Spring 管理的對象&#xff0c;就像工廠流水線上生產的“標準產品”。這些對象不是你自己 new 出來的&#xff0c;而是由 Spring 容器&#xff08;一個超級工廠&#xff09;幫你創建、組裝、管理。 由 Component、Service、Controller 等注解標記的…