Qt   言語   文字列Qt6対応

ホーム   C/C++チュートリアル  

このコーナーは、Qt6 のみに対応しています。


Windowsコンソールアプリの文字化けを解決しました。

それに伴い、このコーナーを Qt6 のみの対応とします。

すでに Windows、Mac、Fedra (RPM系)については、Qt6 をインストールしていましたが、 Debian 系も Qt6 をインストールしていることを前提にします。

Debian 系への Qt6 のインストールは こちら をご覧ください。

2025年4月16日

文字列

この章では Qt の文字列を学習します。

この章では、作業用ディレクトリは strings、ファイル名は strings.cpp に統一します。

任意の場所に strings というディレクトリ (フォルダ) を作ってください。

そしてそ中に、次の strings.cpp を記述して保存してください。

strings.cpp


#include <QTextStream>
#include <QString>

int main(void)
{
  QTextStream out (stdout);
  
  // 次の行はWindowsで日本語の文字化けを防ぐためのものです。
  out.setEncoding(QStringConverter::System);
  
  out << "----------------" << Qt::endl;
  
  QString a {"Qt"};
  //QString a = "Qt";	// 当然こちらでも良いです
	
  a.append ("が大好きです。");
  a.prepend ("私は");
	
  out << a << Qt::endl;
  out << "文字列は" << a.length()
  << "文字です。" << 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;
}

次のようにしても良いです。こちらの場合だと Debian が Qt5 でも対応できます。


#include <QTextStream>
#include <QString>

int win = 0;
#ifdef WIN64
#define win 1
#endif

int main(void)
{
  QTextStream out (stdout);
  
  if (win)
    out.setEncoding(QStringConverter::System);
  
  out << "----------------" << Qt::endl;
  
  QString a {"Qt"};
  //QString a = "Qt";	// 当然こちらでも良いです
	
  a.append ("が大好きです。");
  a.prepend ("私は");
	
  out << a << Qt::endl;
  out << "文字列は" << a.length()
  << "文字です。" << 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;
}


コード説明

  1. #include <QTextStream>
    Qt でテキストの入出力を担当しているクラスです。
  2. #include <QString>
    Qt で文字列を担当しているクラスです。
  3. QTextStream out (stdout);
    テキストストリームが out という名前で標準出力 (ターミナル) を使うと宣言しています。
    out という名前の部分は任意の名前に変えられます。 なぜ iostream ではいけないのかというと、iostream では QStringが使えないからです。
  4. out.setEncoding(QStringConverter::System);
    Windowsの場合、これを記述しないと日本語が文字化けします。
    Qt6ではエンコードとしてUTF-8を使っています。ところが日本語版WindowsではエンコードとしてShift-Jisを使っています。
    このコードはoutオブジェクトのエンコードにシステム(OS)のエンコードをセットします。つまりWindowsの場合はUTF-8からShit-jisに変わります。
    一方、MacやLinuxの場合は、OSのエンコードが元からUTF-8なのでこのコードを実行する意味はありません。CPUへの負荷を考えると削除した方が良いでしょう。
  5. QString a {"Qt"};
    QString を初期化しています。この方法は宣言と同時に初期化する場合にしか使えません。
  6. /QString a = "Qt";
    当然こちらの方法も使えます。
  7. a.append (QString("が大好きです。"));
    QString 文字列の後に文字列を追加すことができます。
  8. a.prepend (QString("私は"));
    QString 文字列の前に文字列を追加することもできます。
  9. out << a << Qt::endl;
    標準出力に a 文字列を出力して、改行しています。QString の場合、改行は Qt::endl; になります。
  10. (QString("文字列は"))
    QString では日本語などの wide byte 文字も使えます。 この部分を QString 宣言しなければいけないかどうは環境によって変わりますが、QString で文字列を作っておいた方が安全です。
  11. a.length()
    length () 関数で QString 文字列の文字数が得られます。length() の代わりに size() も使えます。 が推奨されています。
  12. a = "I am Qt.";
    QString の変数には文字列を再代入することができます。
  13. a { "I am Qt."};
    この方法は使えません。Qstring a {"..."} は宣言と同時に初期化する場合にしか使えません。
  14. a.toUpper()
    QString 文字列をすべて大文字にした文字列を得られます。
  15. a.toLower()
    QString 文字列をすべて小文字にした文字列を得られます。

ビルド

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

// 結果 は同じ

QString の作り方

QString を作るにはいくつかの方法があります。

strings.cpp


#include <QTextStream>
#include <QString>

int main(void)
{
	QTextStream out (stdout);
	
	// 次の行はWindowsで日本語の文字化けを防ぐためのものです。
	out.setEncoding(QStringConverter::System);
	
	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 メソッドでアクセスすることができます。

strings.cpp

#include <QTextStream>
#include <QString>

int main(void)
{
	QTextStream out (stdout);
	
	// 次の行はWindowsで日本語の文字化けを防ぐためのものです。
	out.setEncoding(QStringConverter::System);
	
	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() メソッドで変数の値などを文字列に埋め込むことができます。

strings.cpp


#include <QTextStream>
#include <QString>

int main(void)
{
  QTextStream out (stdout);
  
  // 次の行はWindowsで日本語の文字化けを防ぐためのものです。
  out.setEncoding(QStringConverter::System);
	
	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個です。

部分文字列

文字列から部分文字列を取り出せます。

strings.cpp


#include <QTextStream>
#include <QString>

int main(void)
{
	QTextStream out (stdout);
	
	// 次の行はWindowsで日本語の文字化けを防ぐためのものです。
	out.setEncoding(QStringConverter::System);
	
	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 文字列をループさせて、各要素を取り出すことができます。

strings.cpp


#include <QTextStream>
#include <QString>

int main(void)
{
	QTextStream out (stdout);
	
	// 次の行はWindowsで日本語の文字化けを防ぐためのものです。
	out.setEncoding(QStringConverter::System);
	
	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 メソッドで比較できます。

strings.cpp


#include <QTextStream>
#include <QString>

int main(void)
{
	QTextStream out (stdout);
	
	// 次の行はWindowsで日本語の文字化けを防ぐためのものです。
	out.setEncoding(QStringConverter::System);
	
	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 はオーバーロードされており、
自動的に目的のメソッドが呼び出されます。

strings.cpp


#include <QTextStream>
#include <QString>

int main(void)
{
	QTextStream out (stdout);
	
	// 次の行はWindowsで日本語の文字化けを防ぐためのものです。
	out.setEncoding(QStringConverter::System);
	
	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 メソッドがあります。

strings.cpp


#include <QTextStream>
#include <QString>

int main(void)
{
	QTextStream out (stdout);
	
	// 次の行はWindowsで日本語の文字化けを防ぐためのものです。
	out.setEncoding(QStringConverter::System);
	
	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 では元の文字列が変更できます。

strings.cpp


#include <QTextStream>
#include <QString>

int main(void)
{
	QTextStream out (stdout);
	
	// 次の行はWindowsで日本語の文字化けを防ぐためのものです。
	out.setEncoding(QStringConverter::System);
	
	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;
}

結果


気持ちの良い季節
気持ちの良い
気持ちの良い家具
文字列は空です。

文字列の左揃え、右揃え

ターミナルに出力されるさい、デフォルトで左揃えなので、ここでは、右揃えについて説明します。

ただし、これは、日本語の場合は正しく揃いません。

strings.cpp


#include <QTextStream>
#include <QString>

int main(void)
{
	QTextStream out (stdout);
	
	// 次の行はWindowsで日本語の文字化けを防ぐためのものです。
	out.setEncoding(QStringConverter::System);
	
	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
 

ソースコードを HTML へ変換する

toHtmlEscaped() メソッドはソースコードなどを HTML 形式に変換してくれます。

まず変換する ソースコード sample.c を用意します

sample.c


 #include <stdio.h>

int main (void)
{
	for (int i=1; i<=8; i++)
	{
		printf ("%d本の薔薇\n", i);
	}
	return 0;
}

続けて strings.cpp を次のように記述します。

strings.cpp


#include <QTextStream>
#include <QFile>

int main(void)
{
	QTextStream out (stdout);
	
	// 次の行はWindowsで日本語の文字化けを防ぐためのものです。
	out.setEncoding(QStringConverter::System);
	
	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;
}

結果

Windows では sample.c を release ディレクトリに移動してから実行します。


 #include &lt;stdio.h&gt;

int main (void)
{
	for (int i=1; i<=8; i++)
	{
		printf (&quot;%d本の薔薇\n&quot;, i);
	}
	return 0;
}


318 visits
Posted: Mar. 30, 2025
Update: Apr. 19, 2025

ホーム   C/C++チュートリアル   目次