QTextStream::fieldWidth()でつまずかない!Qtのテキスト出力エラーと解決策

2025-05-27

QTextStream::fieldWidth() とは

QTextStream::fieldWidth() は、Qtの QTextStream クラスのメンバ関数で、現在設定されている「フィールド幅」を返します。

QTextStream は、ファイルやデバイス、文字列などに対してテキストの読み書きを行うためのクラスです。テキストを出力する際に、特定のフォーマットで出力したい場合に、この「フィールド幅」という概念が重要になります。

フィールド幅とは、出力する項目(数値や文字列など)が占める最小の文字数のことです。例えば、フィールド幅を10と設定した場合、出力する文字列が5文字であっても、合計10文字の幅になるように残りの5文字が指定された埋め文字(パディング文字)で埋められます。

用途

QTextStream::fieldWidth() は、現在のフィールド幅の値を取得する際に使用します。通常、フィールド幅を設定するには QTextStream::setFieldWidth() 関数を使います。

具体的な動作

QTextStream::fieldWidth() が返す値は int 型で、設定されているフィールド幅の文字数を示します。デフォルトでは、フィールド幅は0に設定されており、これは「出力する内容の長さに応じて自動的に幅を調整する」という意味になります。


#include <QTextStream>
#include <QString>
#include <QDebug>

int main() {
    QString outputString;
    QTextStream stream(&outputString);

    // デフォルトのフィールド幅を確認
    qDebug() << "デフォルトのフィールド幅:" << stream.fieldWidth(); // 出力: 0

    // フィールド幅を10に設定
    stream.setFieldWidth(10);
    qDebug() << "設定後のフィールド幅:" << stream.fieldWidth(); // 出力: 10

    // フィールド幅を適用して文字列を出力(右寄せ、デフォルトのパディング文字はスペース)
    stream << "Hello";
    qDebug() << "出力された文字列:" << outputString; // 出力: "     Hello" (スペース5文字+Hello5文字)

    return 0;
}

この例では、stream.fieldWidth() を呼び出すことで、設定されているフィールド幅の値を取得しています。

フィールド幅と一緒に、以下の設定もよく使われます。

  • setPadChar(QChar ch): フィールド幅に満たない部分を埋めるための文字(パディング文字)を設定します。デフォルトはスペースです。
  • setFieldAlignment(QTextStream::FieldAlignment alignment): フィールド内でのテキストの配置(左寄せ、右寄せ、中央寄せなど)を設定します。


フィールド幅が期待通りに適用されない

問題
setFieldWidth() でフィールド幅を設定したにもかかわらず、出力されたテキストの幅が期待通りにならない。

原因とトラブルシューティング

  • データ型とフィールド幅
    数字をフォーマットする場合、setRealNumberPrecision()setNumberFlags() などの設定も出力の長さに影響します。これらの設定によっては、フィールド幅に収まりきらない、あるいは収まりきったとしても期待と異なる表示になることがあります。

    • 解決策
      数値の出力の場合、setRealNumberPrecision() で小数点以下の桁数を調整したり、setNumberFlags() で数値の表示形式(符号の表示、基数の表示など)を確認してください。
  • 他のフォーマット設定との競合
    setFieldAlignment()setPadChar() などの他のフォーマット設定が、フィールド幅の視覚的な結果に影響を与えることがあります。例えば、右寄せ (AlignRight) に設定されているのに、左寄せを期待している場合などです。

    • 解決策
      setFieldAlignment()setPadChar() の設定を確認し、意図した通りの配置とパディング文字になっているか確認してください。
  • endl のパディング
    QTextStream::setFieldWidth() で設定されたフィールド幅は、その後にストリームに挿入されるすべての要素に適用されます。これには endl (改行) も含まれます。そのため、endl が挿定されたフィールド幅でパディングされ、余分なスペースやパディング文字が挿入されることがあります。

    • 解決策
      • 改行の直前に setFieldWidth(0) を呼び出し、改行後に再度必要なフィールド幅を設定し直す。これは qSetFieldWidth() マニピュレータを使うと簡潔に書けます。
        stream << "データ1" << qSetFieldWidth(0) << endl << qSetFieldWidth(10) << "データ2";
        
      • フィールド幅を endl に適用したくない場合は、単純に "\n" を使用する。ただし、endl はバッファをフラッシュする効果もあるため、バッファリングに注意が必要です。
  • setFieldWidth(0) の影響
    setFieldWidth(0) はデフォルト設定であり、「フィールド幅を設定しない(内容の長さに応じて自動調整)」という意味です。もし意図せず setFieldWidth(0) を呼び出している場合、その後の出力には固定幅が適用されません。

    • 解決策
      適切なフィールド幅(0より大きい値)が setFieldWidth() で設定されていることを確認してください。

フィールド幅が負の値になった場合

問題
fieldWidth() が負の値を返す、または setFieldWidth() に負の値を渡してしまった。

原因とトラブルシューティング

  • setFieldWidth() に負の値を渡すことは、Qtのドキュメントでは明示的に定義されていません。通常、フィールド幅は0以上の整数であるべきです。負の値が渡された場合、予期せぬ動作やエラーが発生する可能性があります。
    • 解決策
      setFieldWidth() には常に0以上の整数値を渡すようにしてください。

ストリームの状態異常

問題
テキストが出力されない、または部分的にしか出力されない。

原因とトラブルシューティング

  • ストリームのエラー状態
    QTextStream にエラーが発生した場合、それ以降の操作が失敗することがあります。

    • 解決策
      stream.status() を呼び出して現在のストリームの状態を確認し、エラーが発生している場合は適切な処理を行ってください。例えば、QTextStream::ReadPastEndQTextStream::ReadCorruptData など。
  • バッファのフラッシュ忘れ
    QTextStream は内部バッファを使用しているため、データがすぐに物理的なデバイスに書き込まれないことがあります。特に、プログラムが終了する前に明示的にフラッシュしないと、一部の出力が失われる可能性があります。

    • 解決策
      stream << ... << endl; のように endl を使うか、明示的に stream.flush(); を呼び出す、または QFile などデバイスを閉じる (file.close();) ことでバッファがフラッシュされます。
  • デバイスが正しくオープンされていない
    QTextStream が関連付けられている QIODevice (例: QFile) が、書き込みモードで正しくオープンされていない場合、QTextStream は何も出力できません。

    • 解決策
      QFile::open() の戻り値を確認し、ファイルが正常に開かれていることを確認してください。
    QFile file("output.txt");
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        qDebug() << "ファイルを開けませんでした!";
        return 1;
    }
    QTextStream stream(&file);
    // ...
    

QTextStream::fieldWidth() 自体は情報取得の関数ですが、その値に影響を与える setFieldWidth() や他のフォーマット設定と組み合わせて、期待通りの出力を得るためには、以下の点に注意することが重要です。

  • ストリームがエラー状態になっていないか。
  • QTextStream が関連付けられているデバイスが正しくオープンされ、バッファがフラッシュされているか。
  • setFieldAlignment()setPadChar() など、他のフォーマット設定が意図通りか。
  • endl がフィールド幅の影響を受けていないか、必要に応じて qSetFieldWidth(0) でリセットしているか。
  • setFieldWidth() が期待通りの値で呼び出されているか。


例1: 基本的なフィールド幅の設定と確認

この例では、QTextStreamQString に関連付け、フィールド幅を設定して文字列を出力し、その結果を確認します。fieldWidth() を使って現在の設定値を取得します。

#include <QCoreApplication>
#include <QTextStream>
#include <QString>
#include <QDebug> // デバッグ出力用

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QString outputString; // 出力先のQString
    QTextStream stream(&outputString); // QStringにストリームを関連付け

    qDebug() << "--- 例1: 基本的なフィールド幅の設定と確認 ---";

    // 1. デフォルトのフィールド幅を確認
    qDebug() << "初期のフィールド幅:" << stream.fieldWidth(); // 0が出力されるはず

    // 2. フィールド幅を10に設定
    stream.setFieldWidth(10);
    qDebug() << "設定後のフィールド幅:" << stream.fieldWidth(); // 10が出力されるはず

    // 3. フィールド幅を適用して文字列を出力(デフォルトは右寄せ、スペースでパディング)
    stream << "Hello";
    qDebug() << "出力された文字列1 (幅10): \"" << outputString << "\""; // "     Hello"

    // 4. さらに短い文字列を出力(同じフィールド幅が適用される)
    outputString.clear(); // 出力文字列をクリア
    stream << "Hi";
    qDebug() << "出力された文字列2 (幅10): \"" << outputString << "\""; // "        Hi"

    // 5. フィールド幅をリセット (0に設定)
    stream.setFieldWidth(0);
    qDebug() << "リセット後のフィールド幅:" << stream.fieldWidth(); // 0が出力されるはず

    // 6. リセット後に出力(フィールド幅は適用されない)
    outputString.clear();
    stream << "World";
    qDebug() << "出力された文字列3 (幅なし): \"" << outputString << "\""; // "World"

    return 0;
}

実行結果例

--- 例1: 基本的なフィールド幅の設定と確認 ---
初期のフィールド幅: 0
設定後のフィールド幅: 10
出力された文字列1 (幅10): "     Hello"
出力された文字列2 (幅10): "        Hi"
リセット後のフィールド幅: 0
出力された文字列3 (幅なし): "World"

例2: フィールドの配置(アライメント)とパディング文字の変更

QTextStream::setFieldAlignment()QTextStream::setPadChar() を使って、フィールド内での文字列の配置と、埋める文字を変更する例です。

#include <QCoreApplication>
#include <QTextStream>
#include <QString>
#include <QDebug>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QString outputString;
    QTextStream stream(&outputString);

    qDebug() << "--- 例2: フィールドの配置とパディング文字の変更 ---";

    stream.setFieldWidth(15); // フィールド幅を15に設定

    // 1. デフォルト (AlignRight, スペース)
    outputString.clear();
    stream << "Qt";
    qDebug() << "デフォルト (右寄せ, スペース): \"" << outputString << "\""; // "             Qt"

    // 2. 左寄せ (AlignLeft) に変更
    stream.setFieldAlignment(QTextStream::AlignLeft);
    outputString.clear();
    stream << "Qt";
    qDebug() << "左寄せ (AlignLeft, スペース): \"" << outputString << "\""; // "Qt             "

    // 3. 中央寄せ (AlignCenter) に変更
    stream.setFieldAlignment(QTextStream::AlignCenter);
    outputString.clear();
    stream << "Qt";
    qDebug() << "中央寄せ (AlignCenter, スペース): \"" << outputString << "\""; // "      Qt       "

    // 4. パディング文字を '*' に変更
    stream.setPadChar('*');
    outputString.clear();
    stream << "Qt";
    qDebug() << "中央寄せ (AlignCenter, アスタリスク): \"" << outputString << "\""; // "******Qt*******"

    // 5. 右寄せに戻し、数値を出力
    stream.setFieldAlignment(QTextStream::AlignRight);
    outputString.clear();
    stream << 123;
    qDebug() << "右寄せ (AlignRight, アスタリスク, 数値): \"" << outputString << "\""; // "************123"

    // 6. フィールド幅を一時的にリセットするマニピュレータ (qSetFieldWidth)
    outputString.clear();
    stream << "Item1:" << qSetFieldWidth(5) << 100 << qSetFieldWidth(0) << endl;
    stream << "Item2:" << qSetFieldWidth(5) << 2000 << qSetFieldWidth(0) << endl;
    stream << "Item3:" << qSetFieldWidth(5) << 3 << qSetFieldWidth(0) << endl;
    qDebug() << "qSetFieldWidth を使った出力:\n" << outputString;

    return 0;
}

実行結果例

--- 例2: フィールドの配置とパディング文字の変更 ---
デフォルト (右寄せ, スペース): "             Qt"
左寄せ (AlignLeft, スペース): "Qt             "
中央寄せ (AlignCenter, スペース): "      Qt       "
中央寄せ (AlignCenter, アスタリスク): "******Qt*******"
右寄せ (AlignRight, アスタリスク, 数値): "************123"
qSetFieldWidth を使った出力:
Item1:  *100

Item2:*2000

Item3:    **3

例3: ファイルへの書き込みとフィールド幅の適用

QFileQTextStream を組み合わせて、ファイルにフォーマットされたテキストを書き込む例です。

#include <QCoreApplication>
#include <QTextStream>
#include <QFile>
#include <QDebug>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QString filename = "formatted_output.txt";
    QFile file(filename);

    if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        qWarning("ファイルを開けませんでした: %s", qPrintable(file.errorString()));
        return 1;
    }

    QTextStream stream(&file);

    qDebug() << "--- 例3: ファイルへの書き込みとフィールド幅の適用 ---";

    // ヘッダ行
    stream.setFieldWidth(10);
    stream.setFieldAlignment(QTextStream::AlignCenter);
    stream << "名前" << "数量" << "価格" << endl;
    stream.setFieldWidth(0); // ヘッダ行の後にフィールド幅をリセット
    stream << QString(30, '-') << endl; // 区切り線

    // データ行
    stream.setFieldWidth(10); // フィールド幅を再度設定
    stream.setFieldAlignment(QTextStream::AlignLeft); // 名前は左寄せ
    stream << "リンゴ";
    stream.setFieldAlignment(QTextStream::AlignRight); // 数量は右寄せ
    stream << 15;
    stream.setRealNumberPrecision(2); // 価格は小数点以下2桁
    stream << 120.50 << endl;

    stream.setFieldAlignment(QTextStream::AlignLeft);
    stream << "バナナ";
    stream.setFieldAlignment(QTextStream::AlignRight);
    stream << 8;
    stream << 85.00 << endl;

    stream.setFieldAlignment(QTextStream::AlignLeft);
    stream << "オレンジ";
    stream.setFieldAlignment(QTextStream::AlignRight);
    stream << 20;
    stream << 95.75 << endl;

    file.close();
    qDebug() << "ファイル '" << filename << "' に書き込みました。";

    // ファイル内容の確認 (オプション)
    QFile readFile(filename);
    if (readFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
        QTextStream in(&readFile);
        qDebug() << "\n--- ファイル内容 ---";
        qDebug() << in.readAll();
        readFile.close();
    }

    return 0;
}

実行結果例 (コンソール出力)

--- 例3: ファイルへの書き込みとフィールド幅の適用 ---
ファイル 'formatted_output.txt' に書き込みました。

--- ファイル内容 ---
   名前      数量      価格   
------------------------------
リンゴ            15    120.50
バナナ             8     85.00
オレンジ           20     95.75
   名前      数量      価格   
------------------------------
リンゴ            15    120.50
バナナ             8     85.00
オレンジ           20     95.75


QString::arg() を使用する

QString::arg() は、文字列の書式設定において非常に強力で、QTextStream::fieldWidth() と同様のパディングとアライメントの機能を提供します。特に、単一の文字列をフォーマットして生成する場合に便利です。

特徴

  • 複数の引数を一度にフォーマットできます。
  • アライメント(右寄せ/左寄せ)も指定できます。
  • arg() オーバーロードに fieldWidthfillChar 引数があります。


#include <QCoreApplication>
#include <QString>
#include <QDebug>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    qDebug() << "--- QString::arg() の例 ---";

    // 1. フィールド幅とデフォルトのパディング(スペース、右寄せ)
    qDebug() << QString("値: %1").arg("Hello", 10); // "値:      Hello"
    qDebug() << QString("値: %1").arg(123, 10);     // "値:        123"

    // 2. パディング文字の指定
    qDebug() << QString("値: %1").arg("Hello", 10, QChar('*')); // "値: *****Hello"

    // 3. 左寄せ (負のフィールド幅で指定)
    qDebug() << QString("値: %1").arg("Hello", -10); // "値: Hello     "

    // 4. 複数引数のフォーマット
    qDebug() << QString("名前: %1, 年齢: %2, スコア: %3").arg("太郎", 8, QChar(' ')).arg(30, 3, QChar('0')).arg(95.5, 6, 'f', 2, QChar(' '));
    // "名前: 太郎   , 年齢: 030, スコア:  95.50"

    return 0;
}

利点

  • C++20の std::format に似た、より現代的な構文。
  • 単発の文字列生成に最適。
  • QTextStream オブジェクトを作成する必要がないため、より軽量。

欠点

  • ファイルやデバイスへの直接書き込みには、さらに QFile などが必要。
  • 複数の異なるフォーマット設定を段階的に適用するような、複雑なストリーム処理には向かない。

C++ 標準ライブラリの std::setw (iomanip) を使用する

C++標準ライブラリの <iomanip> ヘッダに含まれるマニピュレータ std::setw を使用する方法です。これは std::coutstd::stringstream などの std::ostream で利用できます。

特徴

  • std::setfill(char) でパディング文字を設定します。
  • std::left, std::right, std::internal でアライメントを設定します。
  • std::setw(width) でフィールド幅を設定します。


#include <QCoreApplication>
#include <iostream>   // 標準出力用
#include <sstream>    // 文字列ストリーム用
#include <iomanip>    // フォーマット用
#include <string>     // std::string 用
#include <QDebug>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    qDebug() << "--- std::setw (iomanip) の例 ---";

    std::stringstream ss; // 文字列を格納するストリーム

    // 1. 基本的なフィールド幅とデフォルトのパディング(スペース、右寄せ)
    ss << std::setw(10) << "Hello" << std::endl;
    ss << std::setw(10) << 123 << std::endl;
    qDebug() << "デフォルト (右寄せ): \n" << QString::fromStdString(ss.str());

    ss.str(""); // ストリームをクリア

    // 2. 左寄せとパディング文字の指定
    ss << std::left << std::setfill('*') << std::setw(10) << "Hi" << std::endl;
    ss << std::right << std::setfill(' ') << std::setw(10) << "Bye" << std::endl; // 右寄せに戻し、スペースでパディング
    qDebug() << "左寄せとパディング文字:\n" << QString::fromStdString(ss.str());

    // 3. 複数の要素をフォーマット
    ss.str("");
    ss << std::left << std::setw(15) << "商品名"
       << std::right << std::setw(5) << "数量"
       << std::right << std::setw(10) << std::fixed << std::setprecision(2) << "価格" << std::endl;
    ss << std::setfill('-') << std::setw(30) << "" << std::endl; // 区切り線
    ss << std::left << std::setfill(' ') << std::setw(15) << "りんご"
       << std::right << std::setw(5) << 10
       << std::right << std::setw(10) << 150.75 << std::endl;
    qDebug() << "複雑なテーブル形式:\n" << QString::fromStdString(ss.str());


    return 0;
}

実行結果例 (コンソール出力)

--- std::setw (iomanip) の例 ---
デフォルト (右寄せ): 
      Hello
        123

左寄せとパディング文字:
Hi********
       Bye

複雑なテーブル形式:
商品名          数量      価格
------------------------------
りんご             10    150.75

利点

  • QTextStream と同様にストリームベースの操作が可能。
  • 既存のC++コードベースに統合しやすい。
  • C++標準ライブラリの一部なので、Qtに依存しない。

欠点

  • QTextStream の一部の便利な機能(例: UTF-8 エンコーディングの自動検出など)は提供されない。
  • QTextStream のように QFileQByteArray に直接関連付けることはできない。通常は std::stringstream を介して QStringQByteArray に変換する必要がある。

C言語スタイルの sprintf / snprintf

C言語の printf ファミリ関数 (sprintf, snprintf など) も、固定幅での文字列フォーマットに使用できます。

特徴

  • %-10s のように、- をつけると左寄せになります。
  • %10s のように、フォーマット指定子内で直接フィールド幅を指定できます。
  • フォーマット文字列 (%s, %d, %f など) を使ってフォーマットを定義します。


#include <QCoreApplication>
#include <cstdio>   // sprintf/snprintf 用
#include <string>   // std::string 用
#include <vector>   // バッファ用
#include <QDebug>
#include <QString> // QString に変換するため

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    qDebug() << "--- C言語スタイル (sprintf/snprintf) の例 ---";

    char buffer[100]; // 固定バッファ

    // 1. 基本的なフィールド幅(右寄せ)
    sprintf(buffer, "%10s", "Hello");
    qDebug() << "右寄せ: \"" << QString(buffer) << "\""; // "     Hello"

    // 2. 左寄せ
    sprintf(buffer, "%-10s", "Hi");
    qDebug() << "左寄せ: \"" << QString(buffer) << "\""; // "Hi        "

    // 3. 数値のフォーマット (小数点以下2桁、幅8)
    sprintf(buffer, "%8.2f", 123.456);
    qDebug() << "数値 (幅8, 小数点以下2桁): \"" << QString(buffer) << "\""; // "  123.46"

    // 4. snprintf を使った安全なバッファ管理
    std::string result_str;
    int len = snprintf(nullptr, 0, "名前: %-15s, 年齢: %5d, 価格: %10.2f", "山田", 25, 299.99);
    if (len >= 0) {
        result_str.resize(len); // 必要なサイズにリサイズ
        snprintf(&result_str[0], len + 1, "名前: %-15s, 年齢: %5d, 価格: %10.2f", "山田", 25, 299.99);
        qDebug() << "snprintf を使った出力:\n" << QString::fromStdString(result_str);
    }

    return 0;
}

利点

  • snprintf を使えばバッファオーバーフローを安全に回避できる。
  • C言語の知識があれば馴染みやすい。
  • 非常に高速。

欠点

  • Qtのデータ型(QString など)を直接扱えないため、toStdString()toUtf8().constData() などで変換が必要。
  • パディング文字はデフォルトでスペースのみ。他の文字で埋めるには追加の処理が必要。
  • バッファの管理が必要(snprintf を使う場合でも)。
  • タイプセーフではない(フォーマット文字列と引数の型が一致しないと未定義動作)。

C++20で標準化された std::format は、Pythonの str.format() や C# の複合書式指定機能に似た、現代的でタイプセーフな文字列フォーマット方法です。もしC++20以降を使用できるなら、最も推奨されるアプローチの一つです。C++17以前でも、std::format のベースとなった fmt ライブラリを使用できます。

特徴

  • パフォーマンスが高い。
  • タイプセーフで、コンパイル時に多くのフォーマットエラーを検出できます。
  • {:width} でフィールド幅、{:pad_char<width} でパディング文字とアライメントを指定できます。
  • 波括弧 {} をプレースホルダーとして使用します。

例 (C++20 std::format)

#include <QCoreApplication>
#include <string>
#include <format> // C++20 の <format> ヘッダ
#include <QDebug>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    qDebug() << "--- C++20 std::format の例 ---";

    // 1. 基本的なフィールド幅(右寄せ、デフォルトはスペース)
    qDebug() << QString::fromStdString(std::format("値: {:10}", "Hello")); // "値:      Hello"
    qDebug() << QString::fromStdString(std::format("値: {:10}", 123));     // "値:        123"

    // 2. パディング文字の指定と左寄せ
    qDebug() << QString::fromStdString(std::format("値: {:*<10}", "Hi"));    // "値: Hi********"
    qDebug() << QString::fromStdString(std::format("値: {:*>10}", "Bye"));   // "値: *******Bye"
    qDebug() << QString::fromStdString(std::format("値: {:_^10}", "Center")); // "値: __Center__"

    // 3. 複数引数と様々なフォーマットオプション
    qDebug() << QString::fromStdString(std::format("名前: {:<15}, 年齢: {:0>5}, 価格: {:>10.2f}",
                                                  "鈴木", 45, 599.99));
    // "名前: 鈴木           , 年齢: 00045, 価格:     599.99"

    return 0;
}

利点

  • パフォーマンスも優れている。
  • タイプセーフで、コンパイル時にエラーを検出できる。
  • 多くのフォーマットオプションを柔軟に指定できる。
  • 非常に現代的で、読みやすく、安全。
  • Qtのネイティブ型 (QString など) を直接扱うには、toStdString()toUtf8() などで変換が必要になる場合がある。
  • C++20以降のコンパイラと標準ライブラリのサポートが必要(または fmt ライブラリの導入)。
方法利点欠点主な用途
QTextStream::setFieldWidth()QtのストリームI/Oとシームレスに統合、ファイル/デバイス書き込みに便利設定が状態を持つため、途中でリセットが必要な場合があるログファイル、レポート、構造化されたテキスト出力
QString::arg()軽量、モダンな構文、単一の文字列フォーマットに最適複雑なストリーム処理には不向きUI表示用の文字列、単一のフォーマット済み文字列生成
std::setw (iomanip)C++標準、Qtに依存しない、ストリームベースQt型との連携に変換が必要、QTextStreamほど機能は豊富ではない一般的なC++プログラムでのテキストフォーマット
sprintf/snprintf高速、C言語の知識があれば使いやすいタイプセーフではない、バッファ管理が必要、パディング文字が限定的パフォーマンスが最優先される場合、C言語との連携
std::format (fmt)現代的、タイプセーフ、高機能、高性能C++20以降のサポートが必要、Qt型との連携に変換が必要新しいプロジェクト、モダンなC++開発