QString を char* に型変換するには、まず QString::toLatin1()、QString::toUtf8() や QString::toLocal8Bit() などで QByteArray 型に変換します。
次に data() または constData() を呼出して、QByteArray オブジェクトに保存されている char* 型または const char* データへのポインタを取出します。
逆に、char* を QString に型変換するには、QLatin1String 型または const char* 型の実引数を取る QString コンストラクターを使うか、QString のスタティックメンバー関数 fromLatin1()、fromLocal8Bit() や fromUtf8() などの関数を使います。const char* 型の実引数を取る QString コンストラクターは、fromUtf8() 関数を使って変換するので、UTF-8 でエンコードされている場合に使えます。
main.cpp:
#include <QCoreApplication>
#include <QLocale>
#include <QString>
#include <QByteArray>
#include <QDebug>
#include <iostream>
int main(int argc, char** argv)
{
QCoreApplication app(argc, argv);
const QString nativeCountryName = QLocale::system().nativeCountryName();
QByteArray ba = nativeCountryName.toLocal8Bit();
const char* cp = ba.constData();
std::cout << "toLocal8Bit: " << cp << std::endl;
QString string = QString::fromLocal8Bit(cp);
qDebug() << "fromLocal8Bit:" << string;
ba = nativeCountryName.toUtf8();
cp = ba.constData();
std::cout << "toUtf8: " << cp << std::endl;
string = QString::fromUtf8(cp);
qDebug() << "fromUtf8:" << string;
const QString countryName("Japan");
ba = countryName.toLatin1();
cp = ba.constData();
std::cout << "toLatin1: " << cp << std::endl;
string = QString::fromLatin1(cp);
qDebug() << "fromLatin1:" << string;
}
コードの説明
QLocale::system() でシステムロケールを取得し、nativeCountryName() を呼び出すと日本語環境では国名を日本語で返します。
QString::toLocal8Bit() 関数は、言語環境のエンコードでバイト列を格納した QByteArray オブジェクトを返します。
QByteArray::constData() は、内部のバイト列のアドレスを const char* 型で返します。
QByteArray::constData() を呼ぶ前に QByteArray 型の変数に一旦保存する必要があることに注意しましょう。
つまり、以下のようにすると cp を参照しようしたときには、データを保存している QByteArray オブジェクトが存在しなくなってしまっているので、ポインターが無効になり、参照すると未定義動作になるためです。必ずクラッシュするとは限らず、偶然読める場合もあります。
const char* cp = nativeCountryName.toLocal8Bit().constData();
逆に、言語環境のエンコードのバイト列 const char* を QString に型変換するには、QString::fromLocal8Bit() を使います。
QString::toUtf8() 関数は、UTF-8 でエンコードされたバイト列を格納した QByteArray オブジェクトを返します。
逆に、UTF-8 でエンコードされたバイト列を QString に型変換するには、QString::fromUtf8() を使います。
QString::toLatin1() 関数は、Latin-1 でエンコードされたバイト列を格納した QByteArray オブジェクトを返します。
逆に、Latin-1 でエンコードされたバイト列を QString に型変換するには、QString::fromLatin1() を使います。
toLocal8Bit: 日本
fromLocal8Bit: "日本"
toUtf8: 日本
fromUtf8: "日本"
toLatin1: Japan
fromLatin1: "Japan"
Unix や Linux などの UTF-8 環境での実行結果です。
toLocal8Bit: 日本
fromLocal8Bit: "日本"
toUtf8: 譌・譛ャ
fromUtf8: "日本"
toLatin1: Japan
fromLatin1: "Japan"
Windows の SJIS 環境での実行結果です。toUtf8 が文字化けしているのは SJIS 環境で UTF-8 文字列を表示しようとしたためです。
サンプルコード
stringconversion.zip
適用条件と確認
Qt 6 / Qt Coreの例です。通信やファイルの仕様がUTF-8なら toUtf8()/fromUtf8() を対にして使います。toLocal8Bit() の結果と端末の表示文字コードは環境依存です。上のWindows出力はSJIS設定時の例で、すべてのWindowsに共通ではありません。
cp は ba が破棄されるか内容変更で内部領域が無効になるまでだけ使用します。非同期処理やAPIがポインターを保存する場合は、その処理が終わるまで QByteArray を保持してください。途中にNULを含むデータは fromUtf8(cp, length) のように長さも渡します。Latin-1では日本語を表現できません。
サンプルを実行し、変換前後のQStringが一致することを確認します。端末の文字化けとバイト列の変換失敗は分けて判断してください。
参考資料