2011-03-25 2 views
2

sprintf 작업에서 얻은 문자열의 길이를 예상해야합니다. 어떻게해야합니까? 즉, 아래 코드에서 값 50을 harcoding하지 않는 방법은 무엇입니까?sprintf 결과 길이 추정

double sum; 
char* resultString; 
.. 

resultString = new char[50]; //how can I avoid hardcoding 50 here? 
sprintf(resultString,"[%e]",sum); 
+6

왜 C++ 대신'string'을 사용합니까? –

+0

참고로,'[someInitializedIntVariable]'인덱스에서 변수를 보낼 수도 있습니다. – Mahesh

답변

3

snprintf(char *buffer, int buf_size, const char *format, ...);을 사용하십시오. sprintf은 안전하지 않습니다.

그러나 나는 당신이 C++를 사용하는 읽기, 그래서 나는이 같은 이제 stringstream을 사용합니다 :

#include <iostream> 
#include <sstream> 

double sum; 
std::stringstream buf(std::stringstream::in | std::stringstream::out); 
std::string resultString; 
.. 

buf << "[" << std::scientific << sum << "]"; 
resultString = buf.str(); 
+0

는 C++을 사용할 수 없습니다. 0x – Emie

+1

이것은 어떻게 C++ 0x입니까? – orlp

+0

'error : incomplete type 'std :: stringstream이 중첩 된 이름 지정자에서 사용되었습니다' – Emie

1

적절한 방법의 sprintf를 사용하지 않습니다. C++ (표준 iostreams 기능을 포함하되 이에 국한되지 않음)에서 출력을 형식화하기위한 확장 가능하고 안전한 많은 방법이 있습니다. C로 코딩하면 snprintf를 사용하십시오.

3

가장 좋은 방법은이 모든 대신 std::stringstream 사용하는 것 피하기 위해 :

std::stringstream buffer; 
buffer << std::scientific << sum; 
std::string resultString = buffer.str(); 
8

snprintf은 버퍼가 충분히 크다 경우 기록 된 것입니다 문자의 수를 반환합니다. 두 번 호출 할 수 있습니다. 길이를 얻으려면 한 번, 문자열을 실제로 포맷하려면 다시 호출하십시오.

2

좋은 빠른 방법은 snprintf의 고정 크기 버퍼를 사용하는 것입니다.이 버퍼는 버퍼가 충분히 클 경우 인쇄 할 문자 수를 반환합니다. 그 반환 값이 버퍼가 충분히 크지 않다는 것을 나타내는 경우, 현재 알려진 크기의 malloc() 또는 new를 사용하십시오. 더 느리지 만 간단한 대안은 항상 힙에서 할당 한 asprintf()을 찾는 것입니다. 몇 줄에 위에 자신의 asprintf()을 구현할 수 있습니다.

0

printf와 같은 기능을 사용하는 동안 각 번호에 길이를 제공하는 옵션이 있습니다.

printf ("% .2s", "12345");

이 예제는 처음 두 문자 만 인쇄합니다. 이렇게하면 필요한 최대 크기를 예측/제한 할 수 있습니다.

그렇지 않으면 표준을 사용하여 다른 사람

보통
0

에 의해 제안 많은 좋은 답변이 있습니다 :: 이제 stringstream가 정답이다. 아직 C 코드를 인터페이싱 할 때 printf (fmt, ...)를 사용해야하므로 std :: stringstream을 사용할 수 없습니다. 이러한 경우 하나는 여전히 같은 가변 길이 문자열을 포맷 할 수 있습니다 :

static void append_format(std::string& s, const char* format, va_list vl) 
{ 
    auto cur_length = s.length(); 
    auto sz = vsnprintf(NULL, 0, format, vl); 
    s.resize(cur_length + sz); 
    auto sz2 = vsnprintf(&s[cur_length], sz + 1, format, vl); 
    assert(sz2 == sz); 
} 

static void example_usage() 
{ 
    std::string s; 
    append_format(s, "%s %dD world", "hello", 3); // s == "hello 3D world" 
    append_format(s, ", PI= ~%f", 3.14); // s == "hello 3D world, PI= ~3.14" 
    std::cout << s; 
} 

메모를, printf와 그 클론 안전 입력하지 않기 때문에이 방법은 안전 입력되지 않았는지 확인합니다. 하지만 결과 문자열이 얼마나 오랫동안 유효한지에 관계없이 유효한 호출에 대한 버퍼 오버런이 발생하지 않습니다