sprintf에 해당하는 C ++?


82

그 알 std::cout의 동등한 C ++입니다 printf.

C ++에 해당하는 것은 무엇입니까 sprintf?

답변:


66

std::ostringstream

예:

#include <iostream>
#include <sstream> // for ostringstream
#include <string>

int main()
{
  std::string name = "nemo";
  int age = 1000;
  std::ostringstream out;  
  out << "name: " << name << ", age: " << age;
  std::cout << out.str() << '\n';
  return 0;
}

산출:

name: nemo, age: 1000

3
나는 sprintf가 stdout에 쓴다고 생각하지 않습니다. 위의 삽입 문을 제거합니다.
Raffi Khatchadourian

78
이것은 원격으로 어떻게 유사 sprintf (...)합니까? 데이터를 임의로 형식화 할 수 없으며 <<연산자를 사용하여 스트림에 데이터를 공급할 때 알려진 유형에 의존해야합니다 .
Andon M. Coleman

나는 이것에 대해 @ AndonM.Coleman과 동의해야합니다. 이것은 실제로 sprintf 대체물이 아닙니다. 이것은 좀 더 비슷할 것이지만 이것은 Qt입니다.
lpapp

@vinkris가 그의 대답에서 말했듯이 iomanip은 서식을 달성합니다. stdoit에 인쇄하는 대신 "result = out.str ()"이라고 말합니다.
Dmitri 2014 년

sprintf / snprintf는 사용자가 할당 한 문자 배열로 포맷 및 인쇄를 허용하며 스택에있을 수 있습니다. snprintf ()의 경우 오버런이 없는지 확인합니다. 여기서 우리는 메모리를 여러 번 할당하고 호출자는 직접 액세스 할 수 없습니다. 출력을 얻으려면 문자열로 변환해야합니다. 사용자 버퍼를 취하는 사용자 정의 std :: streambuf가있는 std :: ostream은 더 나은 일치가 될 것입니다. 물론 ostream / streambuf의 생성 / 파괴는 더 많은 비 효율성을 추가합니다.
MGH

34

2019 년 8 월 업데이트 :

C ++ 20에 std::format. 참조 구현은 {fmt} 입니다. printf()지금 대안을 찾고 있다면 이것은 새로운 "표준"접근 방식이 될 것이며 고려할 가치가 있습니다.

실물:

Boost.Format을 사용하십시오 . 그것은 printf구문, 형식 안전성, std::string결과 및 기타 멋진 것들을 많이 가지고 있습니다. 당신은 돌아 가지 않을 것입니다.


14
... 당신은 당신의 실행 ..의 크기에 대해 우려하지 않는 : P
pradyunsg

이것이 얼마나 많은 영향을 미칠까요? Boost 종속성은 헤더 전용이며 링크가 없습니다. 맞습니까?
Ken Williams

1
@KenWilliams 예, Boost.Format은 헤더 전용입니다. 내 Mac에서 간단한 "hello, world"테스트가 10kB에서 78kB로 증가합니다. 실제 프로젝트에서 추가 크기는 컴파일 단위에서 분할되며 (올바른 링커 옵션 제공) 유형 안전성은 다른 이점을 제공합니다.
janm


7

iomanip 헤더 파일을 사용하여 출력 스트림을 형식화 할 수 있습니다. 이것을 확인 하십시오 !


왜 누군가 이것을 반대표를 던졌습니까? iomanip은 스트림에서 형식을 지정하는 순수한 C ++ 방식이 아닙니까? 여기서 목표는 iomanip으로 달성되는 C 스타일 문자열에 데이터를 저장하지 않는 것입니다.
Dmitri 2014 년

7

다음은 C ++ sprintf를위한 멋진 함수입니다. 스트림을 너무 많이 사용하면 스트림이 추악해질 수 있습니다.

std::string string_format(const std::string &fmt, ...) {
    int size=100;
    std::string str;
    va_list ap;

    while (1) {
        str.resize(size);
        va_start(ap, fmt);
        int n = vsnprintf(&str[0], size, fmt.c_str(), ap);
        va_end(ap);
   
        if (n > -1 && n < size) {
            str.resize(n); // Make sure there are no trailing zero char
            return str;
        }
        if (n > -1)
            size = n + 1;
        else
            size *= 2;
    }
}

C ++ 11 이상에서, 표준 : : 문자열은 연속 스토리지를 사용하도록 보장 그게 끝 '\0'이로 캐스팅 할 법적, 그래서 char *사용 &str[0].

가변 인수는 참조에 의한 전달을 따르지 않아야하며 C ++는 필요하지 않은 경우 문자열을 복사하지 않는 것이 좋습니다. 이 경우 수정됩니다.

std::string string_format(std::string fmt, ...) {

아주 좋은 해결책! 나는 그것을 사용 에 더 가깝게 맞추기 위해 stackoverflow.com/a/3742999/15161 여기에 적용했습니다 sprintf.
slashmais

10
하지만 불법 : (char*) str.c_str()캐스트 버림 const.
MSalters 2013 년

또한 숨어있는 버퍼 오버플로 문제가 있습니다
Barney Szabolcs

@MSalters 맞습니다. C ++ 11에서이를 수행하는 합법적 인 방법이 있습니다.
whitequark

@whitequark : 답으로 자유롭게 추가하세요. Stack Overflow에서는 새로운 답변을 허용하기 위해 좋은 질문이 열려 있습니다.
MSalters

0

동일한 효과를 얻으려면 stringstream을 사용하십시오. 또한 <cstdio>snprintf를 포함 하고 계속 사용할 수 있습니다 .


0

정확히 무엇을 계획하는지에 따라 다른 옵션보다 유용하고 관용적 sprintf()std::to_string()수 있습니다.

void say(const std::string& message) {
 // ...
}

int main() {
  say(std::to_string(5));
  say("Which is to say " + std::to_string(5) + " words");
}

std::to_string()IMHO 의 가장 큰 장점은 문자열 sprintf()화를 꿈도 꾸지 못하는 추가 유형을 지원하도록 쉽게 확장 할 수 있다는 것입니다 Object.toString().

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.