【Qt入門】QTextStream::numberFlags()を使った数値出力のカスタマイズ方法
QTextStream::numberFlags()
は、Qt プログラミングにおける QTextStream
クラスのメンバ関数で、数値の出力形式を制御するためのフラグ群を取得します。
QTextStream
は、テキストの読み書きを便利に行うためのクラスで、ファイル、バイト配列、QString
など、様々なI/Oデバイスを扱えます。数値を出力する際に、例えば16進数で表示するか、常に符号を表示するか、小数点以下の桁数を強制するか、といった細かな設定をしたい場合に numberFlags()
で現在の設定を取得し、setNumberFlags()
で変更します。
numberFlags()
が返す QTextStream::NumberFlags
とその内訳
QTextStream::NumberFlags
は、QTextStream::NumberFlag
列挙型の値の組み合わせ(ビットフラグ)です。主な NumberFlag
の種類とその意味は以下の通りです。
-
QTextStream::UppercaseDigits
:- 10より大きい数字(A, B, C...)を表現する際に、大文字を使用します。主に16進数で影響します。
- 例:
0xABCDEF
(16進数)
-
QTextStream::UppercaseBase
:- 基数を示すプレフィックス("0x", "0b" など)を大文字で表示します。
ShowBase
と組み合わせて使用します。- 例:
0XABC
(16進数)
-
QTextStream::ForceSign
:- 正の数に対しても常に符号(
+
)を表示します。 - 例:
-5
は-5
、5
は+5
- 正の数に対しても常に符号(
-
QTextStream::ForcePoint
:- 浮動小数点数を表示する際に、小数点以下の桁がなくても常に小数点を表示します。
- 例:
123.
ではなく123.0
(このフラグが設定されている場合)
-
QTextStream::ShowBase
:- 基数(10進数、16進数など)を示すプレフィックス(例: 16進数の "0x"、8進数の "0"、2進数の "0b")を表示します。
- 例:
0xABC
(16進数),0123
(8進数),0b1011
(2進数)
#include <QTextStream>
#include <QString>
#include <QDebug> // デバッグ出力用
int main() {
QString output;
QTextStream stream(&output);
// デフォルトのフラグを表示(通常は空のQFlags)
qDebug() << "デフォルトのフラグ:" << stream.numberFlags();
// 16進数で基数を表示し、大文字を使用する設定
stream.setNumberFlags(QTextStream::ShowBase | QTextStream::UppercaseBase | QTextStream::UppercaseDigits);
stream << "Hex: " << 255 << Qt::endl; // 0xFF と出力されます
// 正の数に符号を強制表示する設定
stream.setNumberFlags(stream.numberFlags() | QTextStream::ForceSign); // 既存のフラグにForceSignを追加
stream << "Signed: " << 100 << " " << -50 << Qt::endl; // +100 -50 と出力されます
// 小数点を強制表示する設定
stream.setNumberFlags(stream.numberFlags() | QTextStream::ForcePoint);
stream << "Float: " << 123.0 << Qt::endl; // 123.0 と出力されます
qDebug() << "設定後の出力:\n" << output;
return 0;
}
QTextStream::numberFlags()
は数値の出力フォーマットを制御するための便利な機能ですが、使い方を誤ると意図しない結果になることがあります。以下に、よくあるエラーとそのトラブルシューティングを挙げます。
フラグの設定が期待通りに反映されない
問題
setNumberFlags()
でフラグを設定したはずなのに、数値の出力フォーマットが変わらない。
原因とトラブルシューティング
-
QTextStream マニピュレータとの混同
QTextStream
には、showbase
、forcesign
、hex
、dec
といったマニピュレータも用意されています。これらは内部的にsetNumberFlags()
やsetIntegerBase()
を呼び出しますが、マニピュレータとsetNumberFlags()
を併用すると、意図しない挙動になる可能性があります。一貫した方法でフォーマットを設定することをお勧めします。// BAD: マニピュレータとsetNumberFlags()を混在させると、どちらが優先されるか分かりにくい stream << Qt::hex << 255; stream.setNumberFlags(QTextStream::ForceSign);
-
既存のフラグをクリアし忘れている
特定のフラグを無効にしたい場合は、現在のフラグからビット AND (&
) 演算とビット否定 (~
) 演算を組み合わせてクリアする必要があります。// ShowBase フラグを無効にする stream.setNumberFlags(stream.numberFlags() & ~QTextStream::ShowBase);
-
既存のフラグを上書きしている
setNumberFlags()
は、引数で渡されたフラグで既存のすべてのフラグを上書きします。特定のフラグを追加したい場合は、現在のフラグを取得してビット OR (|
) 演算で結合する必要があります。// BAD: ForceSign だけを有効にして、ShowBaseは無効になる stream.setNumberFlags(QTextStream::ForceSign); // GOOD: 既存のフラグにForceSignを追加 stream.setNumberFlags(stream.numberFlags() | QTextStream::ForceSign);
-
setNumberFlags() の呼び出し忘れ、または間違ったタイミングでの呼び出し
setNumberFlags()
は、その呼び出し以降の出力に影響します。数値を出力する前に正しく設定されているか確認してください。複数の数値を出力する間にフラグを変更したい場合は、その都度setNumberFlags()
を呼び出す必要があります。QTextStream stream(&output); stream << 123; // デフォルトのフォーマット stream.setNumberFlags(QTextStream::ShowBase | QTextStream::Hex); // ここで設定 stream << 255; // 0xff と出力される stream.setNumberFlags(QTextStream::ForceSign); // 別途設定 stream << 100; // +100 と出力される
浮動小数点数の出力が期待通りにならない
問題
ForcePoint
フラグを設定しても、浮動小数点数の小数点以下の挙動が期待通りにならない。
原因とトラブルシューティング
-
setRealNumberPrecision() や setRealNumberNotation() との兼ね合い
QTextStream::ForcePoint
は、小数点以下の桁数がなくても小数点を表示するフラグですが、浮動小数点数の全体の表示形式(固定小数点表記、指数表記など)や精度はsetRealNumberPrecision()
やsetRealNumberNotation()
で制御されます。これらの設定がForcePoint
の挙動に影響を与えることがあります。例えば、
setRealNumberPrecision(0)
を設定すると、小数点以下が表示されなくなるため、ForcePoint
の効果も薄れてしまいます。stream.setNumberFlags(QTextStream::ForcePoint); stream.setRealNumberPrecision(2); // 小数点以下2桁を表示 stream << 123.0; // 123.00 と出力される(ForcePointの効果で小数点が表示される) stream.setRealNumberPrecision(0); // 小数点以下を表示しない stream << 123.0; // 123 と出力される(ForcePointの効果が打ち消される)
16進数や2進数で数字が小文字になる、またはプレフィックスが表示されない
問題
ShowBase
や UppercaseDigits
を設定したのに、16進数の 'a'〜'f' が小文字になったり、"0x" などのプレフィックスが表示されない。
原因とトラブルシューティング
-
setIntegerBase() の設定
QTextStream
はデフォルトで基数を自動検出しますが、setIntegerBase()
を使用して明示的に基数を設定できます。16進数として出力したい場合は、stream << Qt::hex
マニピュレータを使用するか、setIntegerBase(16)
を呼び出す必要があります。stream.setNumberFlags(QTextStream::ShowBase | QTextStream::UppercaseDigits); // デフォルトは10進数なので、この設定だけでは16進数にはならない stream << 255; // 255 と出力される // 16進数として出力するには、Qt::hex マニピュレータを使うか、setIntegerBase() を呼び出す stream << Qt::hex << 255; // 0xFF と出力される
-
ShowBase フラグの設定漏れ
UppercaseBase
やUppercaseDigits
は、ShowBase
と組み合わせて初めて意味をなします。基数を示すプレフィックス("0x" など)を表示しない限り、大文字/小文字の区別は関係ありません。// BAD: UppercaseDigitsだけでは、0xFF のように大文字にならない stream.setNumberFlags(QTextStream::UppercaseDigits); stream << Qt::hex << 255; // ff と出力される // GOOD: ShowBase と UppercaseDigits を組み合わせる stream.setNumberFlags(QTextStream::ShowBase | QTextStream::UppercaseDigits); stream << Qt::hex << 255; // 0xFF と出力される
QTextStream の状態がリセットされる場合がある
問題
一度設定した numberFlags
が、予期せずデフォルトに戻ってしまったり、他の設定に上書きされたりする。
原因とトラブルシューティング
-
reset() の呼び出し
QTextStream::reset()
メソッドは、ストリームの書式設定(フィールド幅、パディング文字、数値フラグ、実数表記など)をデフォルト値にリセットします。デバッグ目的などでreset()
を呼び出している場合、設定が失われる可能性があります。 -
新しい QTextStream オブジェクトの作成
QTextStream
オブジェクトを新しく作成すると、そのオブジェクトはデフォルトの状態(フラグもデフォルト)で初期化されます。前のQTextStream
オブジェクトの設定は引き継がれません。 同じストリームに対して一貫した設定を維持したい場合は、同じQTextStream
インスタンスを使い続けるか、必要に応じて毎回設定を再適用する必要があります。
全体的なトラブルシューティングのヒント
- Qt ドキュメントを参照する
QTextStream
の詳細な動作や、各フラグの意味、他のフォーマット設定との兼ね合いについては、Qt の公式ドキュメントが最も正確な情報源です。 - シンプルなコードでテストする
複雑な処理の中で問題が発生している場合、QTextStream
の設定と出力に関する部分だけを切り出して、最小限のコードで動作を確認すると原因を特定しやすくなります。 - 現在のフラグを確認する
stream.numberFlags()
の戻り値をqDebug()
などで出力し、設定が正しく反映されているかを確認します。
QTextStream::numberFlags() 関連プログラミング例
QTextStream::numberFlags()
は、数値の出力フォーマットを制御するための非常に便利な機能です。ここでは、さまざまなフラグの組み合わせと、それらが数値出力にどのように影響するかを示す具体的なコード例を挙げます。
準備
これらの例を実行するには、Qtプロジェクトを作成し、.pro
ファイルに QT += core
を追加するか、CMakeを使用している場合は find_package(Qt6 COMPONENTS Core)
を追加して Qt::Core
をリンクするように設定してください。
// main.cpp
#include <QCoreApplication> // コンソールアプリケーションの場合
#include <QTextStream>
#include <QString>
#include <QDebug> // デバッグ出力用
// ヘルパー関数: フラグ設定と出力を簡素化
void printNumberWithFlags(QTextStream& stream, int number, const QString& description) {
stream << description << ": " << number << Qt::endl;
}
void printDoubleWithFlags(QTextStream& stream, double number, const QString& description) {
stream << description << ": " << number << Qt::endl;
}
int main(int argc, char *argv[]) {
QCoreApplication a(argc, argv); // コンソールアプリケーションの基本的な初期化
QString outputString;
QTextStream stream(&outputString, QIODevice::WriteOnly); // QStringへの書き込みストリーム
qDebug() << "--- QTextStream::numberFlags() の例 ---";
// ----------------------------------------------------
// 1. デフォルトの動作
// ----------------------------------------------------
qDebug() << "\n--- 1. デフォルトの動作 ---";
// デフォルトでは、ほとんどのフラグは設定されていません。
// 整数は10進数、符号は負の数のみ、浮動小数点数は必要に応じて小数点が表示されます。
stream.setNumberFlags(QTextStream::NumberFlags()); // 明示的にデフォルトにリセット
stream << "Default Int: " << 123 << Qt::endl;
stream << "Default Negative Int: " << -45 << Qt::endl;
stream << "Default Double (no frac): " << 789.0 << Qt::endl;
stream << "Default Double (with frac): " << 12.345 << Qt::endl;
// ----------------------------------------------------
// 2. 基数表示 (ShowBase) と大文字 (UppercaseBase, UppercaseDigits)
// ----------------------------------------------------
qDebug() << "\n--- 2. 基数表示と大文字 ---";
// 16進数、8進数、2進数で基数を表示し、数字を大文字にします。
stream.setNumberFlags(QTextStream::ShowBase | QTextStream::UppercaseBase | QTextStream::UppercaseDigits);
// 16進数として出力するには、Qt::hex マニピュレータまたは setIntegerBase(16) が必要
stream << Qt::hex; // 基数を16進数に設定
printNumberWithFlags(stream, 255, "Hex (ShowBase, Uppercase)"); // 0XFF
stream << Qt::oct; // 基数を8進数に設定
printNumberWithFlags(stream, 64, "Oct (ShowBase)"); // 0100 (UppercaseBaseは8進数には影響しない)
// Qt 6以降で利用可能な2進数出力 (Qt 5では直接のQTextStream::binマニピュレータはない場合があります)
// 2進数出力は一般的にQString::number()でより柔軟に扱われますが、QTextStreamで制御する場合は setIntegerBase(2)
stream.setIntegerBase(2); // 基数を2進数に設定
printNumberWithFlags(stream, 10, "Binary (ShowBase)"); // 0B1010
stream.setIntegerBase(10); // 基数を10進数に戻す
// ----------------------------------------------------
// 3. 符号の強制表示 (ForceSign)
// ----------------------------------------------------
qDebug() << "\n--- 3. 符号の強制表示 (ForceSign) ---";
// 正の数にも '+' 符号を表示します。
stream.setNumberFlags(QTextStream::ForceSign);
printNumberWithFlags(stream, 100, "Signed Positive Int"); // +100
printNumberWithFlags(stream, -50, "Signed Negative Int"); // -50
// ----------------------------------------------------
// 4. 小数点の強制表示 (ForcePoint)
// ----------------------------------------------------
qDebug() << "\n--- 4. 小数点の強制表示 (ForcePoint) ---";
// 浮動小数点数で、小数点以下の桁が0でも常に小数点を表示します。
stream.setNumberFlags(QTextStream::ForcePoint);
// setRealNumberPrecision() も併用して表示桁数を調整できます
stream.setRealNumberPrecision(2); // 小数点以下2桁を表示
printDoubleWithFlags(stream, 123.0, "ForcePoint Double (0 frac)"); // 123.00
printDoubleWithFlags(stream, 45.678, "ForcePoint Double (with frac)"); // 45.68 (精度設定により丸められる)
stream.setRealNumberPrecision(-1); // デフォルトの精度に戻す
// ----------------------------------------------------
// 5. フラグの組み合わせと解除
// ----------------------------------------------------
qDebug() << "\n--- 5. フラグの組み合わせと解除 ---";
// 既存のフラグを維持しつつ、新しいフラグを追加
stream.setNumberFlags(stream.numberFlags() | QTextStream::ShowBase | QTextStream::UppercaseDigits);
stream << Qt::hex; // 16進数に設定
printNumberWithFlags(stream, 170, "Combined (ForceSign, ShowBase, UppercaseDigits)"); // +0XAA
// 特定のフラグを解除 (ビット否定 ~ とビットAND & を使用)
stream.setNumberFlags(stream.numberFlags() & ~QTextStream::ForceSign); // ForceSignを解除
printNumberWithFlags(stream, 170, "ForceSign Removed (ShowBase, UppercaseDigits)"); // 0XAA
// すべてのフラグを解除 (デフォルトに戻す)
stream.setNumberFlags(QTextStream::NumberFlags()); // または QTextStream::reset() を使用
printNumberWithFlags(stream, 99, "All Flags Removed"); // 99
// ----------------------------------------------------
// 6. QTextStream::reset() によるリセット
// ----------------------------------------------------
qDebug() << "\n--- 6. QTextStream::reset() によるリセット ---";
stream.setNumberFlags(QTextStream::ShowBase | QTextStream::ForceSign | QTextStream::ForcePoint);
stream << "Before reset: " << +0XFF << " " << 10.0 << Qt::endl;
stream.reset(); // すべての書式設定フラグをリセット
stream << "After reset: " << 255 << " " << 10.0 << Qt::endl;
// 最終的な出力文字列を表示
qDebug() << "\n--- 最終的な出力文字列 ---";
qDebug() << outputString;
return a.exec();
}
上記のコードを実行すると、以下のような出力(qDebug()
による出力と、outputString
の最終的な内容)が得られます。
qDebug() 出力 (実行中の情報)
--- QTextStream::numberFlags() の例 ---
--- 1. デフォルトの動作 ---
--- 2. 基数表示と大文字 ---
--- 3. 符号の強制表示 (ForceSign) ---
--- 4. 小数点の強制表示 (ForcePoint) ---
--- 5. フラグの組み合わせと解除 ---
--- 6. QTextStream::reset() によるリセット ---
--- 最終的な出力文字列 ---
"Default Int: 123\n"
"Default Negative Int: -45\n"
"Default Double (no frac): 789\n"
"Default Double (with frac): 12.345\n"
"Hex (ShowBase, Uppercase): 0XFF\n"
"Oct (ShowBase): 0100\n"
"Binary (ShowBase): 0B1010\n"
"Signed Positive Int: +100\n"
"Signed Negative Int: -50\n"
"ForcePoint Double (0 frac): 123.00\n"
"ForcePoint Double (with frac): 45.68\n"
"Combined (ForceSign, ShowBase, UppercaseDigits): +0XAA\n"
"ForceSign Removed (ShowBase, UppercaseDigits): 0XAA\n"
"All Flags Removed: 99\n"
"Before reset: +0XFF 10.00\n"
"After reset: 255 10\n"
-
デフォルトの動作
- 整数は符号なしで10進数。
- 負の数は符号付き。
- 浮動小数点数は、小数点以下が0の場合は小数点なし、それ以外はあり。
-
基数表示 (ShowBase) と大文字 (UppercaseBase, UppercaseDigits)
QTextStream::ShowBase
により、16進数では0X
、8進数では0
、2進数では0B
のプレフィックスが付きます。QTextStream::UppercaseBase
により、プレフィックスのx
やb
が大文字になります (0X
,0B
)。QTextStream::UppercaseDigits
により、16進数のa
〜f
がA
〜F
と大文字になります (FF
)。- 重要
16進数で出力するには、stream << Qt::hex;
やstream.setIntegerBase(16);
のように、基数を明示的に設定する必要があります。numberFlags()
は出力形式を制御しますが、基数そのものを変更するものではありません。
-
符号の強制表示 (ForceSign)
QTextStream::ForceSign
を設定すると、正の数にも+
符号が付きます (+100
)。負の数には元々-
が付くので変化はありません。
-
小数点の強制表示 (ForcePoint)
QTextStream::ForcePoint
を設定すると、789.0
のような小数点以下の桁が0の浮動小数点数でも、常に小数点とそれに続く桁(789.00
)が表示されます。setRealNumberPrecision(2)
で小数点以下の桁数を2に設定しているため、123.0
が123.00
に、45.678
が45.68
に丸められています。
-
フラグの組み合わせと解除
stream.setNumberFlags(stream.numberFlags() | QTextStream::ShowBase | QTextStream::UppercaseDigits);
のように、既存のフラグを取得し、ビットOR演算 (|
) を使って新しいフラグを追加するのが正しい方法です。stream.setNumberFlags(stream.numberFlags() & ~QTextStream::ForceSign);
のように、特定のフラグを解除するには、ビットAND演算 (&
) とビット否定演算 (~
) を組み合わせて使用します。stream.setNumberFlags(QTextStream::NumberFlags());
で、すべてのカスタムフラグをクリアし、デフォルトの状態に戻せます。
-
QTextStream::reset() によるリセット
stream.reset()
を呼び出すと、numberFlags
を含むすべての書式設定(フィールド幅、パディング文字、実数表記、精度など)がデフォルト値にリセットされます。これは、一度に多くの設定をデフォルトに戻したい場合に便利です。
QString::number()
これは、数値を QString
に変換する際に最も基本的な方法です。様々なオーバーロードがあり、基数(10進数、16進数など)や浮動小数点数の精度などを指定できます。QTextStream
の状態に依存しないため、特定の数値を単独でフォーマットしたい場合に非常に便利です。
特徴
- 整数と浮動小数点数で異なるオーバーロードがある。
- 個別の数値変換に特化しているため、シンプルで分かりやすい。
QTextStream
の状態(設定されているフラグなど)に影響されない。
例
#include <QString>
#include <QDebug>
int main() {
// 整数
qDebug() << "Decimal:" << QString::number(123);
qDebug() << "Hex (lowercase):" << QString::number(255, 16); // 16進数 (ff)
qDebug() << "Hex (uppercase):" << QString::number(255, 16).toUpper(); // 16進数 (FF)
qDebug() << "Binary:" << QString::number(10, 2); // 2進数 (1010)
// 浮動小数点数
qDebug() << "Double (default):" << QString::number(123.456); // 123.456
qDebug() << "Double (fixed, 2 decimal places):" << QString::number(123.456, 'f', 2); // 123.46
qDebug() << "Double (scientific, 3 decimal places):" << QString::number(12345.67, 'e', 3); // 1.235e+04
qDebug() << "Double (general, 2 precision):" << QString::number(12.345, 'g', 2); // 12
// 符号の強制表示(QString::number()自体には直接的なフラグはないため、条件分岐で対応)
int val = 50;
QString signedString = (val >= 0 ? "+" : "") + QString::number(val);
qDebug() << "Signed:" << signedString; // +50
return 0;
}
QString::arg() (書式文字列による置換)
QString::arg()
は、printf-style の書式指定に似た、または Python の str.format()
に近い柔軟な文字列置換機能を提供します。数値を文字列に埋め込む際に、フィールド幅、パディング、基数などを細かく制御できます。
特徴
- 引数の型によって自動的に適切なオーバーロードが選択される。
- フィールド幅、パディング文字、基数、浮動小数点数の表記形式(固定、科学、一般)、精度を引数で指定できる。
- 複数の値を一度にフォーマットし、テンプレート文字列に埋め込むのに適している。
例
#include <QString>
#include <QDebug>
int main() {
// 整数
// %1 は最初の引数、d は10進数
qDebug() << QString("Decimal: %1").arg(123); // Decimal: 123
// 16進数、フィールド幅4、先頭ゼロ埋め、大文字
// %L1 はローカライズされた大文字 (Qt 6以降のQString::arg()で利用可能)
qDebug() << QString("Hex: %1").arg(255, 4, 16, QChar('0')).toUpper(); // Hex: 00FF
// 符号付き、フィールド幅5、右寄せ
qDebug() << QString("Signed: %+1").arg(100, 5, 10); // Signed: +100
qDebug() << QString("Signed: %+1").arg(-50, 5, 10); // Signed: -50
// 浮動小数点数
// f は固定小数点表記、.2 は小数点以下2桁
qDebug() << QString("Double (fixed, 2 decimal): %1").arg(123.456, 0, 'f', 2); // Double (fixed, 2 decimal): 123.46
// 科学表記、精度3
qDebug() << QString("Double (scientific, 3 precision): %1").arg(12345.67, 0, 'e', 3); // Double (scientific, 3 precision): 1.235e+04
// 複数の引数
qDebug() << QString("Value 1: %1, Value 2 (hex): %2").arg(42).arg(255, 0, 16); // Value 1: 42, Value 2 (hex): ff
return 0;
}
C++ 標準ライブラリ (<iomanip> と <format>)
Qtアプリケーションでも、C++標準ライブラリのフォーマット機能を使用できます。
<iomanip> (C++11/14/17 まで)
これは、std::cout
などの std::ostream
に適用するマニピュレータを提供します。QTextStream
とは直接的な関係はありませんが、同じプログラム内で std::cout
や std::stringstream
を使ってフォーマットを行う場合に選択肢となります。
特徴
QTextStream::numberFlags()
と同様に、ストリームの状態を変更するが、setw()
などを除いてほとんどのマニピュレータは「sticky」(一度設定すると、リセットされるまでその状態が続く)。std::hex
,std::showbase
,std::fixed
,std::setprecision
など。std::ostream
系(std::cout
,std::stringstream
など)に適用される。
例
#include <iostream> // std::cout, std::endl
#include <iomanip> // std::hex, std::showbase, std::setprecision, std::fixed, std::setfill, std::setw
#include <sstream> // std::stringstream (文字列への出力)
#include <string>
int main() {
std::stringstream ss;
// 16進数、基数表示、大文字
ss << std::hex << std::showbase << std::uppercase << 255 << std::endl; // 0XFF
// 符号の強制表示
ss << std::dec << std::showpos << 100 << " " << -50 << std::endl; // +100 -50
// 小数点の強制表示、固定小数点表記、精度2
ss << std::fixed << std::setprecision(2) << std::showpoint << 123.0 << " " << 45.678 << std::endl; // 123.00 45.68
// フィールド幅と埋め文字
ss << std::setfill('*') << std::setw(10) << 123 << std::endl; // *******123
std::cout << ss.str();
return 0;
}
<format> (C++20 以降)
C++20 で導入された <format>
ライブラリは、Python の str.format()
に非常に近い、現代的で安全、かつ強力な書式設定機能を提供します。これは今後のC++における文字列フォーマットの標準となるでしょう。
特徴
- Qt 6.x 以降では、一部のQt型(
QString
など)に対するstd::format
のサポートが追加される可能性があり、よりシームレスになることが期待されます。 std::string
を返すため、QtのQString
と組み合わせる場合はQString::fromStdString()
を使う必要がある。- パフォーマンスも優れている。
- 非常に柔軟な書式指定ミニ言語を持つ。
- 型安全で、
printf
のような書式指定子のミスマッチによるバグを防ぐ。
#include <format> // C++20 以降
#include <iostream>
#include <string>
#include <QString> // Qtを使用する場合
int main() {
// 整数
std::string s1 = std::format("Decimal: {}", 123);
std::string s2 = std::format("Hex (lowercase): {:x}", 255); // hex (ff)
std::string s3 = std::format("Hex (uppercase): {:X}", 255); // HEX (FF)
std::string s4 = std::format("Hex (with base): {:#x}", 255); // hex (0xff)
std::string s5 = std::format("Binary (with base): {:#b}", 10); // binary (0b1010)
// 符号の強制表示
std::string s6 = std::format("Signed Positive: {:+}", 100); // +100
std::string s7 = std::format("Signed Negative: {:+}", -50); // -50
// 浮動小数点数
std::string s8 = std::format("Double (fixed, 2 decimal): {:.2f}", 123.456); // 123.46
std::string s9 = std::format("Double (scientific, 3 precision): {:.3e}", 12345.67); // 1.235e+04
std::string s10 = std::format("Double (force point, no frac): {:#.0f}", 789.0); // 789.
std::string s11 = std::format("Double (general, 2 precision): {:.2g}", 12.345); // 12
// フィールド幅と埋め文字
std::string s12 = std::format("Padded: {:*>10}", 123); // *******123
std::cout << s1 << "\n" << s2 << "\n" << s3 << "\n" << s4 << "\n"
<< s5 << "\n" << s6 << "\n" << s7 << "\n" << s8 << "\n"
<< s9 << "\n" << s10 << "\n" << s11 << "\n" << s12 << std::endl;
// Qtアプリケーションでの使用例
QString qtString = QString::fromStdString(std::format("Qt string from format: {}", 42));
qDebug() << qtString;
return 0;
}
-
C++標準ライブラリの機能を使いたい、またはC++20以降のモダンなフォーマットを使いたい場合
<iomanip>
や<format>
を使用します。ただし、QString
との相互変換が必要になる場合があります。特にC++20の<format>
は、将来性も考えると非常に魅力的な選択肢です。 -
QTextStream でストリーム全体の設定を一括で制御したい場合
QTextStream::setNumberFlags()
や他のQTextStream
の設定(setRealNumberPrecision()
,setIntegerBase()
など)が適しています。これは、ファイルやネットワークストリームなど、大量のデータを一貫したフォーマットで出力する際に特に有用です。 -
テンプレート文字列に複数の値を埋め込みたい場合
QString::arg()
が非常に強力で柔軟性があります。Qtの慣習にも合っています。 -
簡単な数値変換や個別のフォーマット
QString::number()
が最もシンプルで直接的です。