Qt   言語   文字列

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

文字列

現在、Windows のコンソールアプリでは日本語が文字化けします。
ただし、GUI アプリについては各文字列を、特殊なコードを使うことなく、そのまま、日本語に変えても文字化けは起こりません。
Windows のコンソールアプリについては、いろいろと試しましたが、まだ解決策は見つかっていません。
私の環境が Qt6.8.x、Visua Studio 2022、Windows 11 Arm64 だからかもしれません。
とりあえず、すべての GUI アプリ、および Windows 以外のコンソールアプリでは文字化けが起こらないのでこのまま進むことにします。
2025年4月1日

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

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

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

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

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;
}


コード説明

  1. #include <QTextStream>
    Qt でテキストの入出力を担当しているクラスです。
  2. #include <QString>
    Qt で文字列を担当しているクラスです。
  3. QTextStream out (stdout);
    テキストストリームが out という名前で標準出力 (ターミナル) を使うと宣言しています。
    out という名前の部分は任意の名前に変えられます。 なぜ iostream ではいけないのかというと、iostream では QStringが使えないからです。
  4. QString a {"Qt"};
    QString を初期化しています。この方法は宣言と同時に初期化する場合にしか使えません。
  5. /QString a = "Qt";
    当然こちらの方法も使えます。
  6. a.append (QString("が大好きです。"));
    QString 文字列の後に文字列を追加すことができます。
  7. a.prepend (QString("私は"));
    QString 文字列の前に文字列を追加することもできます。
  8. out << a << Qt::endl;
    標準出力に a 文字列を出力して、改行しています。QString の場合、改行は Qt::endl; になります。
  9. (QString("文字列は"))
    QString では日本語などの wide byte 文字も使えます。 この部分を QString 宣言しなければいけないかどうは環境によって変わりますが、QString で文字列を作っておいた方が安全です。
  10. a.length()
    length () 関数で QString 文字列の文字数が得られます。length() の代わりに size() も使えます。 が推奨されています。
  11. a = "I am Qt.";
    QString の変数には文字列を再代入することができます。
  12. a { "I am Qt."};
    この方法は使えません。Qstring a {"..."} は宣言と同時に初期化する場合にしか使えません。
  13. a.toUpper()
    QString 文字列をすべて大文字にした文字列を得られます。
  14. 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

// 結果
----------------
遘√・Qt縺悟、ァ螂ス縺阪〒縺吶・
譁・ュ怜・縺ッ11譁・ュ励〒縺吶・

I am Qt.
I AM QT.
i am qt.
----------------

// 残念ながら文字化けします。今から原因を探ります。

色々試しましたが、Windows の文字化けは直りませんでした。とりあえず先に進みます。
またどこかで解決策が見つかるでしょう

QString の作り方

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

strings.cpp


#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 メソッドでアクセスすることができます。

strings.cpp

#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() メソッドで変数の値などを文字列に埋め込むことができます。

strings.cpp


#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個です。

部分文字列

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

strings.cpp


#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 文字列をループさせて、各要素を取り出すことができます。

strings.cpp


#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 メソッドで比較できます。

strings.cpp


#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 はオーバーロードされており、
自動的に目的のメソッドが呼び出されます。

strings.cpp


#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 メソッドがあります。

strings.cpp


#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 では元の文字列が変更できます。

strings.cpp


#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;
}

結果


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

文字列の左揃え、右揃え

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

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

strings.cpp


#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
 

ソースコードを 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);
	
	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 &lt;stdio.h&gt;

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


18 visits
Posted: Mar. 30, 2025
Update: Apr. 01, 2025

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