Qt 開發中,`QString` (Qt 核心)、`std::string` (C++ 標準庫)、`char*` (C 風格) 三種字串類型並存,頻繁互轉。本文整理最常用、最高效的轉換方法,釐清所有權與編碼陷阱,附帶 `int` 轉 `QString` 實用技巧。
關鍵:轉換涉及編碼轉換,Qt 5/6 預設 `toStdString()`/`fromStdString()` 使用 UTF-8,`toLocal8Bit()`/`fromLocal8Bit()` 使用系統本地編碼 (Windows 為 GBK/CP936,Linux 為 UTF-8)。
| 來源 → 目標 | 代碼 | 說明 |
|---|---|---|
| std::string → QString | QString qtStr = QString::fromStdString(stdStr); | 推薦 (Qt 5+),假設 stdStr 為 UTF-8 |
QString qtStr = QString::fromLocal8Bit(stdStr.c_str()); | 假設 stdStr 為系統本地編碼 | |
| QString → std::string | std::string stdStr = qtStr.toStdString(); | 推薦 (Qt 5+),輸出 UTF-8 |
std::string stdStr = qtStr.toLocal8Bit().toStdString(); | 輸出系統本地編碼 (Qt 5 需兩步) | |
| char* → QString | QString qtStr = QString::fromUtf8(chStr); | 假設 chStr 為 UTF-8 |
QString qtStr = QString::fromLocal8Bit(chStr); | 假設 chStr 為本地編碼 | |
| QString → char* (臨時) | const char *chStr = qtStr.toUtf8().constData(); | 生命週期綁定臨時 QByteArray,**勿存指標** |
const char *chStr = qtStr.toLocal8Bit().constData(); | 同上,本地編碼版 | |
| QString → char* (持久) | QByteArray ba = qtStr.toUtf8(); char *buf = strdup(ba.constData()); | 需自行 `free(buf)`,或用 `std::string` 管理 |
| std::string → char* | const char *chStr = stdStr.c_str(); | 指標有效期同 stdStr,**勿修改** |
| char* → std::string | std::string stdStr(chStr); | 構造函數複製內容,安全 |
// 錯誤!toUtf8() 返回臨時 QByteArray,語句結束即銷毀,指標懸空
const char *bad = qtStr.toUtf8().constData();
// 正確:延長 QByteArray 生命週期
QByteArray ba = qtStr.toUtf8();
const char *good = ba.constData(); // ba 存活期間指標有效
Qt 5 移除 `toAscii()`,Qt 6 移除 `toLatin1()`。請改用 `toUtf8()` 或 `toLocal8Bit()`。
// int → QString
int a = 10;
QString b = QString::number(a); // "10"
QString c = QString::number(a, 16); // "a" (十六進位)
QString d = QString("%1").arg(a, 4, 10, QChar('0')); // "0010" (格式化)
// QString → int (帶錯誤檢查)
bool ok;
int val = "123".toInt(&ok); // ok=true, val=123
int val2 = "abc".toInt(&ok); // ok=false, val2=0
// 浮點數格式化
QString pi = QString::number(3.14159, 'f', 2); // "3.14" (固定2位小數)
// 輔助函數:安全獲取 UTF-8 char*
inline std::string qtToUtf8(const QString &s) { return s.toUtf8().toStdString(); }
inline QString utf8ToQt(const std::string &s) { return QString::fromUtf8(s.c_str()); }
// 用法
std::string utf8 = qtToUtf8(qtStr);
QString qt = utf8ToQt(utf8);
掌握這些轉換模式,能消除 Qt 專案中 90% 的字串編碼與生命週期 Bug,讓你專注於業務邏輯而非字元編碼糾結。