C++ std::format, 포맷 문자열로 출력하는 법
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 — 활성화된 특수화와 타입별 형식화 규칙을 확인합니다.