/

🇰🇷 한국어 | 🇺🇸 English

std::format은 C++20부터 제공되는 <format> 헤더의 함수로, 포맷 문자열에 맞춰 인자를 형식화한 결과 문자열을 반환합니다. 문자열 결과가 필요하고 각 값의 표시 형식을 포맷 문자열로 정하고 싶을 때 사용합니다.

텍스트 형식화 라이브러리는 printf 함수 계열의 안전하고 확장 가능한 대안으로 제공되며, 기존 C++ I/O streams 라이브러리를 보완하도록 설계되었습니다. 표준 버전과 구현에 따라 사용할 수 있는 세부 기능이 달라질 수 있으며, 아래 설명은 2026-09-02에 확인한 cppreference 문서 범위에 한정합니다.

C++ std::format은 무엇입니까?

한 줄 답: std::format은 <format>에서 제공하는 C++20 함수로, 포맷 문자열에 따라 인자를 형식화하고 그 결과를 문자열로 반환합니다.

일반 문자열을 다루는 오버로드는 std::string을 반환하고, 넓은 문자열을 다루는 오버로드는 std::wstring을 반환합니다. 각 형태에는 선택적으로 locale을 받는 오버로드가 있으며, locale을 전달하면 locale-specific formatting에 사용됩니다.

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

위 예시에서 일반 문장은 그대로 두고 {} 교체 필드에 42를 형식화해 넣습니다. 포맷 문자열과 인자 형식의 관계는 format_string 및 wformat_string을 통해 생성 시 컴파일 시점에 검사할 수 있습니다. P2216R3 반영 이후 인자 형식에 맞지 않는 포맷 문자열은 컴파일 오류가 됩니다.

포맷 지정이 잘못되면 std::format_error가 던져지며, 결과를 위한 메모리를 할당하지 못하면 std::bad_alloc이 발생할 수 있습니다.

std::format 교체 필드는 어떻게 사용합니까?

한 줄 답: 일반 문자는 결과에 그대로 복사되고, {} 같은 교체 필드는 대응하는 인자를 형식화해 그 위치에 삽입합니다.

포맷 문자열에서 중괄호는 특별한 의미를 가집니다. {{는 리터럴 {을, }}는 리터럴 }를 나타냅니다.

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

교체 필드는 {arg-id?} 또는 {arg-id?:format-spec} 형태입니다. arg-id는 사용할 인자의 인덱스이며, 생략하면 인자를 포맷 문자열에 나타난 순서대로 사용합니다. 하나의 포맷 문자열에서는 인덱스를 직접 쓰는 방식과 자동으로 선택하는 방식을 섞을 수 없습니다.

반대로 포맷 문자열에 대응하는 교체 필드가 없어 사용하지 않은 추가 인자가 남는 것은 허용됩니다.

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

포맷 문자열이 컴파일 시점 상수가 아니거나 해당 검사를 피해야 하는 경우에는 std::vformat을 사용할 수 있습니다.

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

C++26 문서에는 동적 포맷 문자열을 만들고 사용자 지향 형식화 함수에서 바로 사용할 수 있는 std::dynamic_format도 소개되어 있습니다. 실제 사용 가능 여부는 사용하는 표준 모드와 구현을 함께 확인해야 합니다.

std::format 포맷 지정은 어떻게 선택합니까?

한 줄 답: 콜론 뒤의 표준 포맷 지정으로 채움 문자, 정렬, 부호, 대체 형식, 0 채움, 폭, 정밀도, locale, 표시 형식을 선택합니다.

기본 구문은 fill-and-align? sign? #? 0? width? precision? L? type? 순서입니다. 물음표는 각 항목이 선택적이라는 뜻이며, 모든 항목이 모든 형식에 적용되는 것은 아닙니다.

정렬은 <가 필드 시작 쪽, >가 필드 끝 쪽, ^가 가운데를 의미합니다. 정수와 부동소수점의 기본 정렬은 끝 쪽이고, 그 밖의 기본 형식은 시작 쪽입니다. 채움 문자는 { 또는 }가 될 수 없습니다.

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

부호 지정, # 대체 형식, 0 채움은 정수 또는 부동소수점 표시 형식에서 사용할 수 있습니다. 0은 0으로 채우며, 정렬을 함께 지정하면 무시됩니다. printf의 %03.2f 표기는 {:03.2f}로 옮길 수 있습니다.

width는 최소 필드 폭이고 precision은 정밀도 또는 문자열의 최대 추정 폭을 정합니다. 두 값 모두 중첩 교체 필드인 {} 또는 {n}으로 받을 수 있습니다. L은 산술 타입을 locale-specific 형식으로 표시할 때 사용합니다.

정수 표시 형식에는 b·B·c·d·o·x·X가 있고, 부동소수점 표시 형식에는 a·A·e·E·f·F·g·G 등이 있습니다. 필요한 타입과 옵션만 골라 사용하면 됩니다.

std::format, format_to, formatter는 언제 선택합니까?

한 줄 답: 결과 문자열이 필요하면 format, 출력 반복자에 쓰려면 format_to, 타입의 형식화 규칙을 정의하려면 formatter를 선택합니다.

format은 형식화한 결과를 문자열로 반환합니다. format_to는 출력 반복자 out을 통해 결과를 쓰고, 출력된 마지막 문자 다음을 가리키는 반복자를 반환합니다.

format_to_n은 출력 길이를 제한하는 형태로 결과를 출력할 때 살펴볼 함수이고, formatted_size는 형식화 결과에 필요한 문자 수를 구할 때 사용하는 함수입니다. 이 함수들은 모두 C++20 형식화 라이브러리에 포함됩니다.

std::formatter<T, CharT>의 활성화된 특수화는 해당 타입의 형식화 규칙을 정의합니다. 활성화된 특수화가 없으면 그 formatter는 disabled 상태이므로, 모든 타입이 자동으로 형식화되는 것은 아닙니다.

사용자 정의 타입은 std::formatter 특수화를 제공하고 그 안에 constexpr parse와 format을 정의하는 방식으로 형식화 규칙을 추가할 수 있습니다. 이 글에서는 특수화의 역할만 구분하며 구현 튜토리얼은 다루지 않습니다.

std::format은 iostream 및 printf와 무엇이 다릅니까?

한 줄 답: 형식화 라이브러리는 printf 함수 계열의 안전하고 확장 가능한 대안이며, 기존 C++ I/O streams 라이브러리를 대체하기보다 보완하도록 의도되었습니다.

std::format은 포맷 문자열을 사용해 값과 표시 방식을 한 표현 안에서 정하고, 검사 가능한 포맷 문자열에서는 인자 형식과의 불일치를 컴파일 시점에 확인할 수 있습니다. 이 점이 printf 계열의 안전한 대안이라는 공식 설명과 연결됩니다.

iostream과의 관계는 어느 한 방식이 항상 더 빠르거나 더 낫다는 비교가 아닙니다. 이미 stream을 사용하는 코드와 포맷 문자열로 문자열을 만들어야 하는 코드가 서로 다른 선택지를 가질 수 있도록 두 라이브러리를 보완 관계로 이해하면 됩니다.

std::format을 개발할 때 무엇을 확인합니까?

한 줄 답: 결과의 목적지, 포맷 문자열을 알 수 있는 시점, 인자 타입의 형식화 지원 여부를 먼저 확인합니다.

  • 문자열 객체가 필요하면 std::format을 사용합니다.
  • 결과를 출력 반복자에 직접 쓰려면 std::format_to를 사용합니다. 이 함수는 출력 끝 다음을 가리키는 반복자를 반환합니다.
  • 컴파일 시점에 알 수 있는 포맷 문자열은 검사 가능한 format_string 경로를 사용합니다. 실행 중에 정해지는 문자열에는 std::vformat을 검토하고, C++26에서는 std::dynamic_format도 확인합니다.
  • 기본 형식화 규칙이 없는 사용자 정의 타입은 std::formatter 특수화로 규칙을 제공해야 합니다. C++23의 formattable 개념도 이 형식화 가능 여부를 다룹니다.

FAQ

한 줄 답: <format>과 std::format의 역할, 중괄호 이스케이프, 런타임 포맷 문자열의 경로를 구분하면 기본 사용법을 정리할 수 있습니다.

C++에서 포맷 문자열로 결과를 만들려면 무엇을 사용합니까?

<format>을 포함하고 std::format을 사용합니다. 인자를 형식화한 결과 문자열을 반환하며, 일반 문자열 오버로드의 결과는 std::string입니다.

중괄호를 그대로 출력하려면 어떻게 합니까?

리터럴 여는 중괄호에는 {{를, 리터럴 닫는 중괄호에는 }}를 사용합니다.

포맷 문자열을 실행 중에 받아야 하면 무엇을 사용합니까?

컴파일 시점 상수가 아닌 문자열에는 std::vformat을 사용할 수 있습니다. C++26에는 동적 포맷 문자열을 만드는 std::dynamic_format도 있습니다.

format과 format_to는 언제 구분합니까?

결과를 문자열 객체로 받아야 하면 format을 사용하고, 출력 반복자에 직접 쓰려면 format_to를 검토합니다.

사용자 정의 타입도 형식화할 수 있습니까?

활성화된 std::formatter 특수화가 해당 타입의 형식화 규칙을 정의합니다. 사용자 정의 타입에 맞는 특수화를 제공할 수 있습니다.

출처

한 줄 답: 본문은 2026-09-02에 확인한 cppreference의 C++ 형식화 라이브러리 문서만 바탕으로 구성합니다.

  • Formatting library — 라이브러리의 목적과 관련 형식화 함수를 확인합니다.
  • std::format — 오버로드, 교체 필드, 컴파일 시점 검사, 동적 입력 경로를 확인합니다.
  • std::format_to — 출력 반복자에 쓰는 형식화 결과와 반환 반복자를 확인합니다.
  • Standard format specification — 필드 옵션과 표시 형식을 확인합니다.
  • std::formatter — 활성화된 특수화와 타입별 형식화 규칙을 확인합니다.

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.

+ Recent posts