現在、Windows のコンソールアプリでは日本語が文字化けします。
ただし、GUI アプリについては各文字列を、特殊なコードを使うことなく、そのまま、日本語に変えても文字化けは起こりません。
Windows のコンソールアプリについては、いろいろと試しましたが、まだ解決策は見つかっていません。
私の環境が Qt6.8.x、Visua Studio 2022、Windows 11 Arm64 だからかもしれません。
とりあえず、すべての GUI アプリ、および Windows 以外のコンソールアプリでは文字化けが起こらないのでこのまま進むことにします。
2025年4月1日
この章では Qt の文字列を学習します。
この章では、作業用ディレクトリは strings、ファイル名は strings.cpp に統一します。
任意の場所に strings というディレクトリ (フォルダ) を作ってください。
そしてそ中に、次の strings.cpp を記述して保存してください。
#include <QTextStream>
#include <QString>
int main(void)
{
QTextStream out (stdout);
out << "----------------" << Qt::endl;
QString a {"Qt"};
//QString a = "Qt"; // 当然こちらでも良いです
a.append (QString("が大好きです。"));
a.prepend (QString("私は"));
out << a << Qt::endl;
out << (QString("文字列は")) << a.length()
<< (QString("文字です。")) << Qt::endl;
out << Qt::endl;
a = "I am Qt.";
//a { "I am Qt."}; // これは警告が出ます
out << a << Qt::endl;
out << a.toUpper() << Qt::endl;
out << a.toLower() << Qt::endl;
out << "----------------" << Qt::endl;
return 0;
}
strings ディレクトリで作業を続けます。
// プロジェクトを作ります。
qmake -project
// Windows の場合は出来上がった strings.pro の末尾に次の一行を追加します。
CONFIG += console
// Makefile を作ります。
qmake
// 実行ファイルを作ります。
// Mac Linux の場合は make します。
make
// Windows の場合は nmake します。make じゃなく nmake です。
nmake
// エラーが表示されたら、version.cpp を見直して、make あるいは nmake する作業を繰り返します。
// Mac の場合は strings ディレクトリに strings.app ができあがります。
// GUI アプリケーションならこれをダブルクリックすると起動できますが、
// 今回はコマンドラインアプリなので次のようにして実行します
./strings.app/Contents/MacOS/strings
// 結果
----------------
私はQtが大好きです。
文字列は11文字です。
I am Qt.
I AM QT.
i am qt.
----------------
// Linux の場合には strings ディレクトリに strings という実行ファイルが出来上がっていますのでそれをそのまま実行します
./strings
// 結果 は同じ
// Windows の場合には strings ディクトリの中の release ティれクトリに strings.exe が出来上がっています。
// release ディレクトリに移動して、strings.exe を実行します。
strings
// 結果
----------------
遘√・Qt縺悟、ァ螂ス縺阪〒縺吶・
譁・ュ怜・縺ッ11譁・ュ励〒縺吶・
I am Qt.
I AM QT.
i am qt.
----------------
// 残念ながら文字化けします。今から原因を探ります。
色々試しましたが、Windows の文字化けは直りませんでした。とりあえず先に進みます。
またどこかで解決策が見つかるでしょう
QString を作るにはいくつかの方法があります。
#include <QTextStream>
#include <QString>
int main(void)
{
QTextStream out (stdout);
QString a = "山田";
out << a << Qt::endl;
QString b ("田中");
out << b << Qt::endl;
QString c {"佐藤"};
out << c << Qt::endl;
std::string s1 = "鈴木";
QString d = s1.c_str();
out << d << Qt::endl;
std::string s2 = "Jane";
QString e = QString::fromLatin1(s2.data(), s2.size());
out << e << Qt::endl;
char s3[] = "花子";
QString f(s3);
out << f << Qt::endl;
return 0;
}
山田
田中
佐藤
鈴木
Jane
花子
QString 文字列は QChars の配列です。各要素へは [ ] 演算子や at メソッドでアクセスすることができます。
#include <QTextStream>
#include <QString>
int main(void)
{
QTextStream out (stdout);
QString a {"山田太郎"};
out << a[0] << Qt::endl;
out << a[1] << Qt::endl;
out << a.at(2) << Qt::endl;
out << a.at(3) << Qt::endl;
out << "---------------" << Qt::endl;
if (a.at(4).isNull())
{
out << "文字列の範囲外です。" << Qt::endl;
}
return 0;
}
山
田
太
郎
---------------
文字列の範囲外です。
arg() メソッドで変数の値などを文字列に埋め込むことができます。
#include <QTextStream>
#include <QString>
int main(void)
{
QTextStream out (stdout);
QString s1 = "りんごが%1個あります。";
int apple = 10;
out << s1.arg(apple) << Qt::endl;
QString s2 = "%1人で分ければ、一人%2個です。";
int people = 4;
double portion = 2.5;
out << s2.arg(people).arg(portion) << Qt::endl;
return 0;
}
りんごが10個あります。
4人で分ければ、一人2.5個です。
文字列から部分文字列を取り出せます。
#include <QTextStream>
#include <QString>
int main(void)
{
QTextStream out (stdout);
QString s = "りんごが10個あります。";
out << s.right(5) << Qt::endl;
out << s.left (4) << Qt::endl;
out << s.mid(4, 3)<< Qt::endl;
return 0;
}
あります。
りんごが
10個
Qstrings は QChar の配列です。QString 文字列をループさせて、各要素を取り出すことができます。
#include <QTextStream>
#include <QString>
int main(void)
{
QTextStream out (stdout);
QString s = "There are ten windows.";
for (QChar qc: s)
{
out << qc;
}
out << Qt::endl;
for (QChar *i=s.begin(); i!=s.end(); ++i)
{
out << *i;
}
out << Qt::endl;
for (int i=0; i < s.size(); ++i)
{
out << s.at(i);
}
out << Qt::endl;
return 0;
}
There are ten windows.
There are ten windows.
There are ten windows.
QString は compare メソッドで比較できます。
#include <QTextStream>
#include <QString>
int main(void)
{
QTextStream out (stdout);
QString a = {"Windows"};
QString b = {"windows"};
QString c = {"windows\n"};
out << "a is " << a << Qt::endl;
out << "b is " << b << Qt::endl;
out << "c is " << "windows" << """\\n" << Qt::endl;
out << "大文字と小文字を区別した比較" << Qt::endl;
if (QString::compare (a, b) == 0)
{
out << "a and b are equal." << Qt::endl;
} else {
out << "a and b are not equal." << Qt::endl;
}
out << "大文字と小文字を区別しない比較" << Qt::endl;
if (QString::compare (a, b, Qt::CaseInsensitive) == 0)
{
out << "a and b are equal." << Qt::endl;
} else {
out << "a and b are not equal." << Qt::endl;
}
if (QString::compare (b, c) == 0)
{
out << "b and c are equal." << Qt::endl;
} else {
out << "b and c are not equal." << Qt::endl;
}
out << "c の最後の改行文字を取り除くと" << Qt::endl;
c.chop (1);
if (QString::compare (b, c) == 0)
{
out << "b and c are equal." << Qt::endl;
} else {
out << "b and c are not equal." << Qt::endl;
}
return 0;
}
a is Windows
b is windows
c is windows\n
大文字と小文字を区別した比較
a and b are not equal.
大文字と小文字を区別しない比較
a and b are equal.
b and c are not equal.
c の最後の改行文字を取り除くと
b and c are equal.
QString は toInt、toFloat、toLong で、それぞれ整数、float、long に変換できます。
数値は setNum で文字列に変換できます。setNum はオーバーロードされており、
自動的に目的のメソッドが呼び出されます。
#include <QTextStream>
#include <QString>
int main(void)
{
QTextStream out (stdout);
QString s1 {"12"};
QString s2 {"18"};
QString s3, s4;
out << s1.toInt() + s2.toInt() << Qt::endl;
int n1 = 12;
int n2 = 18;
out << s3.setNum(n1) + s4.setNum(n2) << Qt::endl;
return 0;
}
30
1218
QString は QChar の配列です。各文字(character)は、数字であったり、文字(letter)であったり、空白であったり、句読点であったりします。
QChar には、どの種類の文字(character)であるかを確認する、isDigit、isLetter、isSpace、isPunct メソッドがあります。
#include <QTextStream>
#include <QString>
int main(void)
{
QTextStream out (stdout);
int digit = 0;
int letter = 0;
int space = 0;
int punct = 0;
QString s {"10 gnus and 3 apples."};
for (QChar q: s)
{
if
(q.isDigit()) digit++;
else if
(q.isLetter()) letter++;
else if
(q.isSpace()) space++;
else if
(q.isPunct()) punct++;
}
out << "--------------------------" << Qt::endl;
out << s << Qt::endl;
out << "--------------------------" << Qt::endl;
out << QString("There are %1 characters.").arg(s.length()) << Qt::endl;
out << QString("There are %1 letters.").arg(letter) << Qt::endl;
out << QString("There are %1 digits.").arg(digit) << Qt::endl;
out << QString("There are %1 spaced.").arg(space) << Qt::endl;
out << QString("There are %1 punctuation characters.").arg(punct) << Qt::endl;
return 0;
}
--------------------------
10 gnus and 3 apples.
--------------------------
There are 21 characters.
There are 13 letters.
There are 3 digits.
There are 4 spaced.
There are 1 punctuation characters.
QString のメソッドは toUpper のように元の文字列を変更した新しい文字列を返すものもありますが、 多くは元の文字列を変更するメソッドです。
他のプログラミング言語では元の文字列を変更することはできず、変更された新しい文字列を作りますが、Qt では元の文字列が変更できます。
#include <QTextStream>
#include <QString>
int main(void)
{
QTextStream out (stdout);
QString s {"気持ちの良い"};
s.append ("季節");
out << s << Qt::endl;
s.remove (6, 3);
out << s << Qt::endl;
s.replace (6, 2, "家具");
out << s << Qt::endl;
s.clear ();
if (s.isEmpty())
out << "文字列は空です。" << Qt::endl;
return 0;
}
気持ちの良い季節
気持ちの良い
気持ちの良い家具
文字列は空です。
ターミナルに出力されるさい、デフォルトで左揃えなので、ここでは、右揃えについて説明します。
ただし、これは、日本語の場合は正しく揃いません。
#include <QTextStream>
#include <QString>
int main(void)
{
QTextStream out (stdout);
QString s1 {"Name: "};
QString s2 {"What do you do?: "};
QString s3 {"Address: "};
QString s4 {"Marital status: "};
int width = s2.size ();
out << s1.rightJustified(width, ' ') << "Bob\n";
out << s2.rightJustified(width, ' ') << "Nothing\n";
out << s3.rightJustified(width, ' ') << "Japan\n";
out << s4.rightJustified(width, ' ') << "Single\n";
return 0;
}
Name: Bob
What do you do?: Nothing
Address: Japan
Marital status: Single
toHtmlEscaped() メソッドはソースコードなどを HTML 形式に変換してくれます。
まず変換する ソースコード sample.c を用意します
#include <stdio.h>
int main (void)
{
for (int i=1; i<=8; i++)
{
printf ("%d本の薔薇\n", i);
}
return 0;
}
続けて strings.cpp を次のように記述します。
#include <QTextStream>
#include <QFile>
int main(void)
{
QTextStream out (stdout);
QFile file ("sample.c");
if (!file.open (QIODevice::ReadOnly))
{
qWarning ("Cannot open file for reading.");
return 1;
}
QTextStream in (&file);
QString text = in.readAll ();
out << text.toHtmlEscaped() << Qt::endl;
file.close ();
return 0;
}
#include <stdio.h>
int main (void)
{
for (int i=1; i<=8; i++)
{
printf ("%d本の薔薇\n", i);
}
return 0;
}