字符串和 I/O 格式化(现代 C++)

C++ <iostream> 类、函数和运算符支持格式化字符串 I/O。 例如,以下代码演示如何设置 cout 以将整数格式化为十六进制中的输出。 首先,它会保存当前状态以在以后重置,因为一旦将格式状态传递到 cout,除非更改,否则将一直保持不变。 它不仅适用于一行代码。

#include <iostream>
#include <iomanip>

using namespace std;

int main()
{
    ios state(nullptr);

    cout << "The answer in decimal is: " << 42 << endl;

    state.copyfmt(cout); // save current formatting
    cout << "In hex: 0x" // now load up a bunch of formatting modifiers
        << hex
        << uppercase
        << setw(8)
        << setfill('0')
        << 42            // the actual value we wanted to print out
        << endl;
    cout.copyfmt(state); // restore previous formatting
}

此方法是类型安全且可扩展的,但它也是复杂且详细的。

替代格式选项

作为一种替代方法,你可以使用 Boost C++ 库(即使它是非标准库)中的 Boost.Format。 可以从 Boost 网站下载任何 Boost 库。

下面是 Boost.Format 具备的某些优势:

  • 安全:类型安全,并为错误引发异常,例如,规范项目太少或太多。

  • 可扩展:适用于可流式传输的任何类型。

  • 方便:标准 POSIX 和类似的格式字符串。

虽然 Boost.Format 基于安全且可扩展的 C++ <iostream> 设施,但它们未优化性能。 如果需要性能优化,请考虑使用快速且易于使用的 C printfsprintf。 然而,它们既不可扩展,也无法免受漏洞攻击。 (虽然存在安全版本,但它们会产生轻微的性能损失。有关详细信息,请参阅 printf_s、_printf_s_l、wprintf_s、_wprintf_s_lsprintf_s、_sprintf_s_l、swprintf_s、_swprintf_s_l)。

以下代码演示了一些 Boost 格式设置功能。

    string s = str( format("%2% %2% %1%\n") % "world" % "hello" );
    // s contains "hello hello world"

    for( auto i = 0; i < names.size(); ++i )
        cout << format("%1% %2% %|40t|%3%\n") % first[i] % last[i] % tel[i];
    // Georges Benjamin Clemenceau             +33 (0) 123 456 789
    // Jean de Lattre de Tassigny              +33 (0) 987 654 321

另请参阅

欢迎回到 C++
C++ 语言参考
C++ 标准库
<iostream>
<limits>
<iomanip>