HOWTO · C++

C++에서 부동 소수점을 문자열로 변환하는 방법

이 기사에서는 C++에서 float를 문자열로 변환하는 방법을 보여줍니다.

이 페이지의 내용

실행 중인 부동 소수점 값을 빠르게 문자열로 바꾸려면 std::to_string을, 형식을 제어하려면 문자열 스트림을, API가 문자 버퍼를 요구하면 snprintf를 사용하세요. 전처리기의 문자열화는 다른 작업입니다. 소스 토큰을 텍스트로 바꾸므로 프로그램 실행 중 계산된 값을 읽을 수 없습니다.

빠르게 변환하려면 std::to_string 사용하기

<string>의 std::to_string은 부동 소수점 값을 받아 std::string을 반환합니다. 기본 형식으로 충분한 간단한 표시나 로그에 편리합니다. 구체적인 출력 형식은 C++ 라이브러리와 버전에 따라 달라질 수 있으므로 모든 도구 체인에서 소수점 출력이 같다고 가정하지 마세요.

다음 예제를 실행해 보세요.

이 섹션의 코드와 표시되는 레이블 또는 출력은 영어로 유지됩니다.

#include <iostream>
#include <string>

int main() {
  double value = 12.5;
  std::string text = std::to_string(value);
  std::cout << text << '\n';
}

문자열에는 형식화된 텍스트가 담기며, value에 저장된 값 자체는 바뀌지 않습니다. 선택한 소수점 형식에서 표시할 자릿수가 충분하지 않으면 아주 작은 값이 0으로 보일 수 있습니다. 소수점 이하 자릿수가 중요하다면 기본 표현이 원하는 세부 정보를 보존한다고 가정하지 말고 형식 지정 방법을 명시적으로 선택하세요.

문자열 스트림으로 소수점 형식 제어하기

익숙한 스트림 형식 제어 기능을 활용하려면 <sstream>의 std::stringstream을 사용하세요. std::fixed를 지정하면 정밀도는 소수점 이하 자릿수를 뜻하고, <iomanip>의 std::setprecision으로 그 자릿수를 설정합니다. std::fixed를 지정하지 않으면 정밀도는 다른 의미로, 유효 숫자의 개수를 제어합니다.

이 섹션의 코드와 표시되는 레이블 또는 출력은 영어로 유지됩니다.

#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>

int main() {
  double value = 12.34567;
  std::stringstream stream;
  stream << std::fixed << std::setprecision(2) << value;
  std::string text = stream.str();
  std::cout << text << '\n';
}

str()은 문자열을 값으로 반환합니다. C 스타일 문자 포인터가 필요하다면 그 문자열을 보관해 두세요. std::string text = stream.str(); 다음에 const char* ptr = text.c_str();를 실행하면 text가 살아 있고 수정되지 않는 동안 문자가 유효합니다. stream.str()이 반환하는 임시 객체에서 c_str()을 호출한 뒤 해당 전체 식이 끝난 후에도 포인터를 보관하지 마세요. 임시 객체는 식이 끝날 때 소멸합니다.

매크로로 컴파일 시점 상수 문자열화하기

전처리기의 문자열화 연산자 #는 매크로 인수로 작성한 토큰을 문자열 리터럴로 바꿉니다. 소스 코드의 상수에는 유용하지만 실행 중인 부동 소수점 값을 변환하거나 숫자 형식을 지정하지는 않습니다. 매크로 이름을 직접 매크로에 인수로 전달하면 그 이름이 적힌 그대로 문자열화됩니다. 두 단계 매크로를 사용하면 먼저 해당 이름을 확장할 수 있습니다.

이 섹션의 코드와 표시되는 레이블 또는 출력은 영어로 유지됩니다.

#include <iostream>

#define STRINGIZE_INNER(x) #x
#define STRINGIZE(x) STRINGIZE_INNER(x)
#define RATE 2.75

int main() {
  const char* text = STRINGIZE(RATE);
  std::cout << text << '\n';
}

결과는 확장된 소스 토큰을 나타냅니다. float의 실행 중 값 변환이 아니며, 매크로는 반올림, 소수점 자릿수 선택 또는 로캘에 따른 형식 지정을 제공하지 않습니다.

snprintf로 문자 버퍼에 형식화하기

C API가 크기가 제한된 문자 배열을 요구한다면 <cstdio>의 snprintf를 선택하세요. 버퍼 용량을 전달한 다음 반환값을 확인합니다. 음수 반환값은 형식 지정에 실패했음을 뜻하고, 반환값이 용량 이상이면 텍스트 전체가 들어가지 않았다는 뜻입니다. 용량이 0보다 크면 텍스트가 잘린 경우에도 버퍼 끝에는 널 문자가 들어갑니다.

예제의 Formatting failed와 Buffer too small 메시지는 코드 블록의 바이트를 그대로 보존하므로 영어로 표시됩니다.

이 섹션의 코드와 표시되는 레이블 또는 출력은 영어로 유지됩니다.

#include <cstddef>
#include <cstdio>
#include <iostream>

int main() {
  double value = 12.34567;
  char buffer[32];
  int result = std::snprintf(buffer, sizeof buffer, "%.2f", value);

  if (result < 0) {
    std::cout << "Formatting failed\n";
  } else if (static_cast<std::size_t>(result) >= sizeof buffer) {
    std::cout << "Buffer too small\n";
  } else {
    std::cout << buffer << '\n';
  }
}

형식 %.2f는 소수점 이하 두 자리를 요청합니다. 결과를 사용하기 전에 snprintf의 반환값을 확인해 텍스트 전체가 버퍼에 들어갔는지 판단하세요. 용량 인수가 없어 대상 배열의 범위를 넘어 쓸 수 있는 무제한 sprintf는 피하세요.

필요에 따라 변환 방법 선택하기

간단한 실행 중 변환에는 std::to_string부터 사용해 보세요. 소수점 형식을 명시해야 한다면 std::fixed와 std::setprecision을 지정한 문자열 스트림을 사용하세요. 매크로 문자열화는 원하는 텍스트가 컴파일 시점의 토큰에서 나올 때만 사용하고, 크기가 제한된 C 스타일 버퍼에 출력하려면 snprintf를 선택하세요. 어떤 방법을 쓰든 숫자 값과 텍스트 표현을 구분해야 합니다. 형식 지정은 독자에게 보이는 내용을 결정하지만 원래 부동 소수점 값은 바뀌지 않습니다.