본문 바로가기
개발/C++ (98,03,11,14,17,20,23)

Modern C++ : std::format (20)

by snowoods 2025. 10. 12.

Modern C++

 

std::format

 

개요

std::format은 C++20부터 도입된 기능으로, 타입-세이프(type-safe)하며 확장 가능한 방식으로 문자열을 포맷팅합니다. Python의 str.format이나 C#의 String.Format과 유사한 기능을 제공하여 기존의 printf 계열 함수나 iostreams보다 더 안전하고 편리한 대안을 제시합니다.

 

C++ 버전별 주요 키워드 도입 시기

  • C++20: std::format, std::format_to, std::format_to_n이 표준 라이브러리에 도입되었습니다.

 

내용 설명

std::format 라이브러리는 다양한 방식으로 문자열을 생성하고 포맷팅하는 기능을 제공합니다.

  • std::format: 포맷 문자열과 인자들을 받아 포맷팅된 새로운 std::string 객체를 반환합니다. 포맷 문자열 내의 {} 플레이스홀더는 인자들의 순서에 따라 치환됩니다. 인덱스({0}, {1})를 지정하여 순서를 명시적으로 제어할 수도 있습니다.
  • 포맷 지정자(Format Specifiers): 플레이스홀더에 콜론(:)을 추가하여 출력 형식을 세밀하게 제어할 수 있습니다. 예를 들어 {0:08X}는 첫 번째 인자를 8자리 너비의 16진수 대문자(부족한 부분은 0으로 채움)로 포맷팅합니다.
  • std::format_to_n: 미리 할당된 버퍼에 포맷팅된 문자열을 안전하게 기록합니다. 버퍼의 크기를 초과하지 않도록 보장하여 버퍼 오버플로우를 방지합니다.
  • 타입 안정성: 컴파일 타임에 포맷 문자열의 유효성을 검사하여, 인자의 타입과 포맷 지정자가 맞지 않을 경우 컴파일 오류를 발생시킵니다. 이는 printf에서 흔히 발생하는 런타임 오류를 예방합니다.

 

예제 코드

#include <chrono>
#include <format>
#include <iostream>

int main()
{
    const auto name = "John";
    const auto lastname = "Lennon";
    const auto age = 42;

    // 기본적인 문자열 결합 (C++20 이전)
    const auto my_str1 =
        std::string{name} + std::string{lastname} + std::to_string(age);
    std::cout << my_str1 << '\n';

    // std::format을 사용한 포맷팅 (인덱스 지정)
    const auto my_str2 = std::format("{1} {0} is {2}", name, lastname, age);
    std::cout << my_str2 << '\n';

    // 포맷 지정자를 사용한 16진수 출력
    std::cout << std::format("{0} hex is {0:08X}", 42) << '\n';

    // 미리 할당된 버퍼에 포맷팅
    char buf[100]{};
    std::format_to_n(buf, sizeof(buf) - 1, "{} is {}", "John", 42);
    std::cout << buf << '\n';

    return 0;
}

 

실행 결과

JohnLennon42
Lennon John is 42
42 hex is 0000002A
John is 42

 

활용팁

  • std::formatprintf보다 타입 안정성이 뛰어나고, iostreams보다 사용이 간결하여 코드 가독성을 높입니다.
  • 사용자 정의 타입을 포맷팅하려면 std::formatter를 특수화하여 커스텀 포맷팅 로직을 구현할 수 있습니다.
  • 로그 메시지, UI 텍스트, 파일 내용 생성 등 동적으로 문자열을 구성해야 하는 모든 곳에서 유용하게 사용할 수 있습니다.