C++ std::format, 포맷 문자열로 출력하는 법

In C++20, std::format takes a format string, substitutes the supplied arguments, and returns formatted text. Use it when the program needs a string result and the way each value is presented should be described by the format string.

The text-formatting library is documented as a safe, extensible alternative to the printf family and as a complement to the existing C++ I/O streams library. Availability of individual details can depend on the standard version and implementation; the technical scope here follows cppreference as checked on 2026-09-02.

What is C++ std::format?

Short answer: std::format is a C++20 function from <format> that formats arguments according to a format string and returns the resulting string.

The narrow-string overloads return std::string, while the wide-string overloads return std::wstring. Each form also has an overload that accepts an optional locale; when supplied, the locale is used for locale-specific formatting.

std::string message = std::format("The answer is {}.", 42);
// message == "The answer is 42."

The ordinary text in this example remains unchanged, and the {} replacement field receives the formatted value 42. format_string and wformat_string check the format string at construction time. Since P2216R3, a format string that does not match its argument types is a compilation error.

std::format throws std::format_error for a formatting error, and failure to allocate storage for the result can produce std::bad_alloc.

How do std::format replacement fields work?

Short answer: Ordinary characters are copied unchanged, while a replacement field such as {} formats the corresponding argument into that position.

Braces have special meaning in a format string. Write {{ for a literal { and }} for a literal }.

std::format("{{}} = {}", 42);
// "{} = 42"

A replacement field has the form {arg-id?} or {arg-id?:format-spec}. The arg-id is the argument index; when it is omitted, arguments are consumed in order. One format string cannot mix explicit argument indices with automatic indexing.

Unused arguments are allowed. A field does not have to exist for every argument passed to the formatting call.

std::format("{} {}!", "Hello", "world", "something");
// "Hello world!"

When the format string is not a compile-time constant, or when compile-time checking must be avoided, use std::vformat.

std::string fmt = "{} + {}";
int left = 1;
int right = 2;
std::string result = std::vformat(fmt, std::make_format_args(left, right));

The C++26 documentation also describes std::dynamic_format, which creates a dynamic format string that can be passed directly to user-oriented formatting functions. Check the selected standard mode and implementation before relying on a particular facility.

How do you choose a std::format specification?

Short answer: The part after the colon selects fill, alignment, sign, alternate form, zero padding, width, precision, locale, and presentation type.

The documented order is fill-and-align? sign? #? 0? width? precision? L? type?. The question marks mean that each component is optional, and not every option applies to every type.

< aligns at the start of the field, > at the end, and ^ in the center. Integer and floating-point values default to end alignment; other types default to start alignment. The fill character cannot be { or }.

std::format("{:6}", 42);     // "    42"
std::format("{:*<6}", 'x'); // "x*****"

Sign, #, and 0 apply to integer or floating-point presentation types. Zero padding uses zeroes, but is ignored when alignment is also specified. The printf notation %03.2f can be expressed as {:03.2f}.

width sets a minimum field width, while precision controls precision or the maximum estimated width for a string. Both can be supplied through nested replacement fields such as {} or {n}. L requests locale-specific formatting for arithmetic types.

Integer presentation types include b, B, c, d, o, x, and X. Floating-point presentation types include a, A, e, E, f, F, g, and G. Choose only the types and options relevant to the value being formatted.

When should you choose std::format, format_to, or formatter?

Short answer: Choose format for a returned string, format_to for writing through an output iterator, and formatter for defining a type’s formatting rules.

format returns the formatted result as a string. format_to writes through the output iterator out and returns the iterator past the last character it wrote.

format_to_n is the bounded-output form, while formatted_size reports the number of characters needed for the formatted result. These functions belong to the C++20 formatting library.

An enabled specialization of std::formatter<T, CharT> defines the formatting rules for a type. If no enabled specialization exists, that formatter is disabled; formatting support is not automatic for every type.

A user-defined type can provide a std::formatter specialization with constexpr parse and format functions. This article uses that fact to identify the extension point without turning it into an implementation tutorial.

How does std::format differ from iostreams and printf?

Short answer: The formatting library is presented as a safe, extensible alternative to the printf family and as a complement to the existing C++ I/O streams library.

std::format describes both the values and their presentation in a format string. With checked format strings, the relationship between the format string and argument types can be validated at compile time. That is the basis for the library’s documented safety advantage over the printf family.

The relationship with iostreams is not a claim that one approach is always faster or preferable. Existing stream-based code and code that needs a formatted string have different destinations and can use the two libraries as complementary facilities.

What should you check before choosing a std::format path?

Short answer: Start with the destination, when the format string becomes known, and whether the argument type has formatting support.

  • Choose std::format when the operation needs a string object.
  • Choose std::format_to when the formatted result should be written through an output iterator; it returns the iterator past the output.
  • Use the checked format_string path for a format string known at compile time. Consider std::vformat for runtime text, and check std::dynamic_format in C++26.
  • A user-defined type without a built-in formatting rule can provide a std::formatter specialization. The C++23 formattable concept describes this formatting capability.

FAQ

Short answer: Separate the roles of <format> and std::format, escaped braces, and the runtime-formatting paths to cover the core usage model.

What should I use to build a formatted C++ string?

Include <format> and call std::format. It returns the formatted arguments as a string; the narrow-string overload returns std::string.

How do I emit literal braces?

Use {{ for a literal opening brace and }} for a literal closing brace.

What should I use when the format string arrives at runtime?

Use std::vformat for a string that is not a compile-time constant. C++26 also provides std::dynamic_format for creating dynamic format strings.

When should I choose format over format_to?

Choose format when the result should be a string object, and consider format_to when the destination is an output iterator.

Can a user-defined type be formatted?

Yes. An enabled std::formatter specialization defines the type’s formatting rules, and a specialization can be provided for a user-defined type.

Sources

Short answer: The article relies only on cppreference documentation for the C++ formatting library, checked on 2026-09-02.