「Qtの基礎 - 文字列」の版間の差分
325行目: | 325行目: | ||
<br><br> | <br><br> | ||
== | == その他の変換 == | ||
以下の例では、数値が整数の場合はそのまま<code>QString</code>クラスへ変換、数値に小数点が含まれている場合は小数点以下を除去して<code>QString</code>クラスへ変換する関数である。<br> | |||
<br> | |||
<code>QVariant</code>クラスは、多くの異なるデータ型を格納することができる。<br> | |||
この柔軟性により、整数型だけでなく浮動小数点型等の様々な数値型をこの関数に渡すことが可能となる。<br> | |||
<syntaxhighlight lang="c++"> | |||
#include <QCoreApplication> | |||
#include <QVariant> | |||
#include <cmath> | |||
QString convertNumberToString(const QVariant &value) | |||
{ | |||
if (value.type() == QVariant::Int || value.type() == QVariant::LongLong) { | |||
// 数値が整数の場合 | |||
return value.toString(); | |||
// 戻り値が整数型の場合 | |||
//return value.toInt(); | |||
} | |||
else if (value.type() == QVariant::Double) { | |||
// 数値が浮動小数点の場合 | |||
double number = value.toDouble(); | |||
// 戻り値がQStringクラスの場合、小数点以下を切り捨て | |||
double intPart; | |||
std::modf(number, &intPart); | |||
return QString::number(intPart, 'f', 0); // 'f'フォーマットと0桁で小数点以下を除去 | |||
// 戻り値が整数型の場合 | |||
//return static_cast<int>(std::floor(number)); | |||
} | |||
// その他の型の場合は空のQStringを返す | |||
return QString(); | |||
// 戻り値が整数型の場合、その他の型の場合は0を返す | |||
//return 0; | |||
} | |||
int main(int argc, char *argv[]) | |||
{ | |||
QCoreApplication app(argc, argv); | |||
// 整数を渡す例 | |||
QVariant intValue = 42; | |||
QString intResult = convertNumberToString(intValue); | |||
std::cout << QString("整数の結果 : %1").arg(intResult).toStdString() << std::endl; // "42"と表示 | |||
// 浮動小数点数を渡す例 | |||
QVariant floatValue = 42.56; | |||
QString floatResult = convertNumberToString(floatValue); | |||
std::cout << QString("浮動小数点数の結果(小数点以下除去) : %1").arg(floatResult).toStdString() << std::endl; // "42"と表示 | |||
return app.exec(); | |||
} | |||
</syntaxhighlight> | |||
<br><br> | |||
== QStringListクラス == | |||
==== 特定の要素の確認 ==== | ==== 特定の要素の確認 ==== | ||
<code>QStringList</code>クラスの要素群の中に特定の要素が存在する場合、<code>contains</code>メソッドを使用する。<br> | <code>QStringList</code>クラスの要素群の中に特定の要素が存在する場合、<code>contains</code>メソッドを使用する。<br> |
2024年3月22日 (金) 23:18時点における版
概要
数値を文字列に変換する
QString::number()
を使用して、数値を文字列に変換する。
少数を変換する場合、第2引数にe
またはE
を指定すると指数表記、f
を指定すると少数表記になる。
この時、第3引数の数値は、小数点以下の桁数となる。
第2引数にg
またはG
を指定すると、指数表記と少数表記のうち、より簡潔に表現できる方で変換される。
この時、第3引数の数値は、有効桁数となる。
第2引数の詳細は、Qtの公式Webサイトを参照すること。
int i = 10;
qDebug() << QString::number(i); // 10進数として文字列化
qDebug() << QString::number(i, 8); // 8進数として文字列化
qDebug() << QString::number(i, 16); // 16進数として文字列化(アルファベット小文字)
qDebug() << QString::number(i, 16).toUpper(); // 16進数として文字列化(アルファベット大文字)
double d = 12.3456789;
qDebug() << QString::number(d, 'e', 1); // 浮動小数12.3456789を小数点以下1桁で指数表記
qDebug() << QString::number(d, 'e', 7); // 浮動小数12.3456789を小数点以下7桁で指数表記
qDebug() << QString::number(d, 'f', 1); // 浮動小数12.3456789を小数点以下1桁で小数表記 --> 12.3
qDebug() << QString::number(d, 'f', 5); // 浮動小数12.3456789を小数点以下7桁で小数表記 --> 12.34568
qDebug() << QString::number(0.0000001, 'g', 7); // 浮動小数0.0000001を有効桁数7桁で簡潔表記
qDebug() << QString::number(1.2345678, 'g', 7); // 浮動小数1.2345678を有効桁数7桁で簡潔表記
qDebug() << QString((int)'A' + 2); // 16進数 0x0Cが文字Cに変換される
文字列を数値に変換する
QString numStr = "1234";
int i = numStr.toInt(); // i=1234
long l = numStr.toLong(); // l=1234
double d = numStr.toDouble(); // d=1234
文字列の長さや数を取得する
QString txtStr = "ABC123:def12 6";
int sz = txtStr.length(); // 空白を含む文字数 sz=14
int ix = txtStr.indexOf("12"); // 指定文字列を最初に見つけた位置 ix=3
int cnt = txtStr.count("12"); // 指定文字列の個数 cnt=2
QString str = txtStr.at(1); // 指定位置の文字 str="B"
※注意
lengthは0x00も1文字として数える。
文字列の確認
QString txtStr = "ABC123:def126 ";
bool bl = txtStr.contains("F12"); // 指定文字を含むか bl=false
bool bl = txtStr.contains("F12", Qt::CaseInsensitive); // 指定文字を含むか bl=true
bool bl = txtStr.startsWith("A"); // 指定文字から始まるか bl=true
bool bl = txtStr.endsWith("6"); // 指定文字で終わるか bl=false(最後は空白)
// isNullメソッドとisEmptyメソッドは異なる
QString txtStr2 = "";
bool bl = txtStr.isEmpty(); // 空か bl=true
bool bl = txtStr.isNull(); // NULLか bl=false
※注意
CaseInsensitive
を指定する場合、大文字・小文字の区別を無視する。
startsWith
メソッドとendsWith
メソッドも、CaseInsensitive
を指定することができる。
基本的な文字列操作
QString txtStr = "ABC123:def126 ";
QString str = txtStr.mid(1, 3); // 指定位置から指定文字数を切り出す str="BC1"
QString str = txtStr.mid(3); // 指定位置以降の文字列を切り出す str="123:def126 "
QString str = txtStr.left(1); // 先頭から指定文字数を切り出す str="A"
QString str = txtStr.right(2); // 末尾から指定文字数を切り出す str="6 "
QString str = txtStr.toLower(); // アルファベット小文字に変換する str="abc123:def126 "
QString str = txtStr.toUpper(); // アルファベット大文字に変換する str="ABC123:DEF126 "
QString str = txtStr.repeated(2); // 指定回数だけ繰り返す str="ABC123:def126 ABC123:def126 "
以下の例では、元の文字列を書き換えるため、使用する場合は注意が必要である。
QString txtStr = "ABC123:def126 ";
txtStr.replace(3, 2, "xy"); // 指定位置から指定文字数の置き換える txtStr="ABCxy3:def126 "
txtStr.chop(2); // 末尾の指定文字数を削除する txtStr="ABCxy3:def12"
txtStr.insert(1, QString("and")); // 指定位置の前に挿入する txtStr="AandBCxy3:def12"
txtStr.fill('X', 4); // 文字を指定数並べる txtStr="XXXX"
txtStr.setNum(2.5); // 数値を文字列に変換する txtStr="2.5"
文字列の右詰め
QString txtStr = "12345";
QString str = txtStr.rightJustified(8, '0'); // str="00012345"
QString str = txtStr.rightJustified(8, '.'); // str="...12345"
QString str = txtStr.rightJustified(3, '.', true); // str="123"
QString str = txtStr.rightJustified(3, '.', false); // str="12345"
QString str = QString::number(98).rightJustified(4, '0'); // str="0098"
※注意
rightJustified
メソッドの第3引数の初期値は、false
である。true
を指定すると指定桁数に切り詰める。
空白の切り詰め
simplified
メソッドは、空白・タブ・改行をまとめて1つの空白に置き換える。この時、先頭と末尾は削られる。
trimmed
メソッドは、先頭と末尾の空白・タブ・改行を取り除く。
QString txtStr = "\t AB CD\n EF GH\tIJ\n\nKL \n";
QString str = txtStr.simplified(); str="AB CD EF GH IJ KL"
QString str = txtStr.trimmed(); str="AB CD\n EF GH\tIJ\n\nKL"
パディング
以下の例では、1~1000までの整数を0001、0002、0003、...、1000という文字列にパディングしている。
第3引数(初期値 : false)の違いは、第1引数で指定した桁数を超える場合、後ろを切る捨てるか否かの設定である。
for(int i = 1; i <= 1000; i++)
{
qDebug() << QString::number(i).rightJustified(4, '0');
}
for(int i = 1; i <= 1000; i++)
{
qDebug() << QString::number(i).rightJustified(4, '0', true);
}
また、rightJustified
メソッドは、文字列の先頭を空白で埋めるなどもできる。
QStringList list = {"a", "aa", "aaa", "aaaa", "aaaaa"};
for(QString str : list)
{
qDebug() << str.rightJustified(5, ' ');
}
文字列の分割
以下の例では、文字列を区切り文字で分割して、文字列リスト(QStringList)に代入している。
QString txtStr = "ABC123:def12 ";
QStringList list = txtStr.split(":"); // :(コロン)で分割する
QString str = list[0]; // "ABC123"
QString str = list[1]; // "def12 "
以下の例では、ループで文字列リストを処理している。上記と同様の結果になる。
QString txtStr = "ABC123:def12 ";
QStringList list = txtStr.split(":"); // :(コロン)で分割する
for(int i = 0; i < list.count(); i++)
{
QString str = list.at(i); // list[i]でも同じ
}
foreach(QString word, list)
{
QString str = word;
}
文字列の整形
arg
と%
を使用して、文字列を整形できる。
QString str = QString("座標=(%1, %2) サイズ=%3x%4 テキスト=%5").arg(10).arg(20).arg(240).arg(120).arg("メッセージ");
// str="座標=(10, 20) サイズ=240x120 テキスト=メッセージ"
また、printf
のように文字列を整形することもできる。
QString sDt="ABC";
QString str;
// Qt 5.7以前
str.sprintf("%02d:%02d, %cクラス, 0x%04x, (%4.2lf), (%-3d), (%5s), (%.2s)", 9, 2, 'S', 255, 3.1415, 7, qPrintable(sDt), qPrintable(sDt));
// str="09:02, Sクラス, 0x00ff, (3.14), (7 ), ( ABC), (AB)"
// Qt 5.7以降
QString str = QString::asprintf("%02d:%02d, %cクラス, 0x%04x, (%4.2lf), (%-3d), (%5s), (%.2s)", 9, 2, 'S', 255, 3.1415, 7, qPrintable(sDt), qPrintable(sDt));
// str="09:02, Sクラス, 0x00ff, (3.14), (7 ), ( ABC), (AB)"
※注意
半角英数の場合はqPrintable
関数でも表示できるが、全角文字の場合はQString
クラスのtoUtf8().constData()
を使用しないと文字化けする。
また、Qt 5.7以降では、以下のように、QString::asprintf
メソッドが使用できる。
QString str = QString::asprintf("フォーマット", データの並び);
文字列の先頭に挿入
先頭に文字列を挿入する場合、QString
クラスのprepend
メソッドを使用する。
このメソッドは、呼び出された文字列の先頭に指定した文字列を挿入する。
prepend
メソッドは呼び出し元のQString
オブジェクト自体を変更するため、新たに変数を定義する必要はない。
QString str = "piyo fuga"; // 出力 : "piyo fuga"
str.prepend("hoge "); // 出力 : "hoge piyo fuga"
QString型からchar型またはstd::string型へ変換
QString
型はUTF-16でエンコードされているのに対して、char
型またはstd::string
型はどの種類のエンコーディングでもよいことに注意する。
以下の例では、QString
型(UTF-16)からchar
型(UTF-8)またはstd::string
型(UTF-8)へ変換している。
QString strUTF16 = "Sample";
// LinuxまたはMacOSにおいて、UTF-8を使用している場合
std::string strUTF8 = strUTF16.toUtf8().constData();
// toStdStringメソッドは変換される文字列がUTF-8でエンコードされていることを前提としている
// QStringが別のエンコーディング (例: UTF-16) を使用している場合、正しく変換されない可能性があるため注意
std::string strUTF8 = strUTF16.toStdString();
// Windowsにおいて、UTF-8を使用している場合
std::string strCurrentLocale = strUTF16.toLocal8Bit().constData();
また、qPrintable(const QString &str)
マクロも存在しており、これは、<QString型のオブジェクト>.toLocal8Bit().constData()
に展開される。
QString型からQByteArray型へ変換
QString strData = "文字列";
QByteArray byaryData = strData.toUtf8();
// または
#include <QTextCodec>
QString strData = "文字列";
QTextCodec *codec = QTextCodec::codecForName("UTF-8");
QByteArray byaryData = codec->fromUnicode(strData);
QByteArray型からQString型へ変換
QByteArray byaryData = file.readAll();
QString strData = QString::fromUtf8(byaryData);
文字エンコード
Shift-JISからUTF-8へ変換
QTextCodec
クラスは、様々な文字エンコード間での文字列の変換をサポートしている。
以下の例では、QString
クラスに格納されている文字列がShift-JISであると仮定しているが、実際にはQString
クラスは内部的にUTF-16を使用している。
したがって、本来変換が必要なものは、外部から入力されるShift-JISでエンコードされたデータ (例: ファイルやネットワーク経由で受信したデータ) を扱う場合である。
そのため、実務等で使用する場合は、外部データをQByteArray
クラスで受け取り、それをQString
クラスに変換する時にエンコーディングを考慮する必要がある。
// Shift-JISでエンコードされた文字列
QString SJISText = QStringLiteral("こんにちは"); // Shift-JISでエンコードされた文字列
// Shift-JISのコーデックを取得
QTextCodec *codec = QTextCodec::codecForName("Shift-JIS");
// Shift-JISのQByteArrayに変換
QByteArray shiftJISBytes = codec->fromUnicode(SJISText);
// UTF-8の文字列に変換
QString utf8String = QString::fromUtf8(shiftJISBytes);
UTF-8からShift-JISへ変換
以下の例では、QTextCodec::codecForName("Shift-JIS")
でShift-JISのQTextCodecオブジェクトを取得して、
fromUnicode
メソッドを使用してUTF-8エンコードされたQString
クラスをShift-JISエンコードされたQByteArray
クラスに変換している。
QByteArray
クラスはバイナリデータを表すため、この変換により得られたバイト配列をファイルやネットワーク経由で送信する時にShift-JISとして扱うことができる。
ただし、変換プロセス中に文字の損失や変換できない文字がある場合、QTextCodec
クラスはデフォルトでその文字を?
に置換、あるいは、無視する設定がある。
変換の精度を高めるためには、QTextCodec::ConverterOptions
を使用して、変換の挙動を細かく制御することが重要である。
// UTF-8でエンコードされた文字列
QString utf8Text = QStringLiteral("こんにちは");
// Shift-JISのコーデックを取得
QTextCodec *codec = QTextCodec::codecForName("Shift-JIS");
// UTF-8のQStringをShift-JISのQByteArrayに変換
QByteArray shiftJISBytes = codec->fromUnicode(utf8Text);
UTF-8からEUC-JPへ変換
// UTF-8でエンコードされた文字列
QString utf8Text = QStringLiteral("こんにちは");
// EUC-JPのコーデックを取得
QTextCodec *codec = QTextCodec::codecForName("EUC-JP");
// UTF-8の文字列をEUC-JPのQByteArrayに変換
QByteArray eucJPBytes = codec->fromUnicode(utf8String);
// EUC-JPエンコードされたデータを16進数で表示
std::cout << eucJPText.toHex() << std::endl;
その他の変換
以下の例では、数値が整数の場合はそのままQString
クラスへ変換、数値に小数点が含まれている場合は小数点以下を除去してQString
クラスへ変換する関数である。
QVariant
クラスは、多くの異なるデータ型を格納することができる。
この柔軟性により、整数型だけでなく浮動小数点型等の様々な数値型をこの関数に渡すことが可能となる。
#include <QCoreApplication>
#include <QVariant>
#include <cmath>
QString convertNumberToString(const QVariant &value)
{
if (value.type() == QVariant::Int || value.type() == QVariant::LongLong) {
// 数値が整数の場合
return value.toString();
// 戻り値が整数型の場合
//return value.toInt();
}
else if (value.type() == QVariant::Double) {
// 数値が浮動小数点の場合
double number = value.toDouble();
// 戻り値がQStringクラスの場合、小数点以下を切り捨て
double intPart;
std::modf(number, &intPart);
return QString::number(intPart, 'f', 0); // 'f'フォーマットと0桁で小数点以下を除去
// 戻り値が整数型の場合
//return static_cast<int>(std::floor(number));
}
// その他の型の場合は空のQStringを返す
return QString();
// 戻り値が整数型の場合、その他の型の場合は0を返す
//return 0;
}
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
// 整数を渡す例
QVariant intValue = 42;
QString intResult = convertNumberToString(intValue);
std::cout << QString("整数の結果 : %1").arg(intResult).toStdString() << std::endl; // "42"と表示
// 浮動小数点数を渡す例
QVariant floatValue = 42.56;
QString floatResult = convertNumberToString(floatValue);
std::cout << QString("浮動小数点数の結果(小数点以下除去) : %1").arg(floatResult).toStdString() << std::endl; // "42"と表示
return app.exec();
}
QStringListクラス
特定の要素の確認
QStringList
クラスの要素群の中に特定の要素が存在する場合、contains
メソッドを使用する。
QStringList list;
list << "apple" << "banana" << "cherry";
// 特定の要素が存在するかどうかを確認
bool exists = list.contains("hoge");
if (exists) {
qDebug() << "要素\"hoge\"が存在します";
}
else {
qDebug() << "要素\"hoge\"は存在しません";
}
特定の要素の削除
QStringList
クラス内の要素群から特定の要素を削除する。
QStringList
クラスは、QList<QString>
のtypedefであるため、QList
クラスに変換して類似の処理を行うことが可能である。
※注意
QStringList
やその他のQtのコンテナクラスにおいて、std::remove_if
を直接使用することは推奨されていない。
これは、QtのコンテナがC++ STLコンテナと異なる内部実装を持っているためである。
以下の例では、QMutableListIterator
クラスを使用して、QStringList
から特定の要素 (この場合は"hoge") を削除している。
QStringList list = {"foo", "bar", "hoge", "baz"};
QMutableListIterator<QString> i(list);
while (i.hasNext()) {
if (i.next() == "hoge") {
i.remove();
}
}
QtのコンテナクラスはC++ STLと完全な互換性は無いが、QList
クラスに変換した後であればstd::remove_if
メソッドを使用することができる。
以下の例では、std::remove_if
メソッドやQList::erase
メソッドと組み合わせて、特定の要素 (この場合は"hoge") を削除している。
// QStringListからQListへ変換
QStringList list = {"foo", "bar", "hoge", "baz"};
QList<QString> qlist = list;
// 特定の要素を削除するラムダ式 (この場合は、要素"hoge"を削除)
auto newEnd = std::remove_if(qlist.begin(), qlist.end(), [](const QString &value) {
return value == "hoge";
});
// リストから要素を削除
qlist.erase(newEnd, qlist.end());
// QListからQStringListへ変換
list = QStringList::fromList(qlist);