C에서 가변인자의 전체 길이(?)를 구할 수 있나요?

superkkt의 이미지

unsigned char *
dup_str(const unsigned char *format, ...)
{
    va_list ap;
    unsigned char msg[8192];
 
    ASSERT(format);
 
    va_start(ap, format);
    vsnprintf(msg, sizeof(msg), format, ap);
    va_end(ap);
 
    return (unsigned char *) strdup(msg);
}

짧은 문자열을 생성하려고 위와 같은 함수를 만들어서 쓰고 있습니다. 그동안 짧은 문자열에만 사용해서 문제없이 잘 사용을 했는데요. 이 함수에 길이가 8192 바이트를 넘어가는 문자열이 들어가는 일이 생겨서 문제가 생겼습니다.

위 함수에서는 내부 버퍼 사이즈를 8192바이트로 고정해서 사용하고 있는데요. 이것을 가변인자의 총 길이를 구해서 동적으로 생성하고 사용 할 수 있는 방법이 있을까요?

익명사용자의 이미지

http://www.cinsk.org/cfaqs/html/node17.html#SECTION001720000000000000000

딱히 전체문자 길이를 구할수 있는 방법은 없는듯

익명사용자의 이미지

GNU 관련 확장을 한번 사용해보심이...

asprintf

그리고 vsnprintf의 경우 버퍼 인자에 NULL을 주고, 사이즈를 0으로 줄 경우 실제 문자가 쓰여질 경우 필요한 길이를 반환하는 것으로 알고 있습니다. (정확하게 기억이... man page (에도 조금만 언급되어 있군요 ㅠ.ㅠ)

Concerning  the  return  value  of  snprintf,  the SUSv2 and the C99 standard contradict each other: when snprintf is
       called with size=0 then SUSv2 stipulates an unspecified return value less than 1, while C99 allows str to be NULL  in
       this  case,  and  gives the return value (as always) as the number of characters that would have been written in case
       the output string has been large enough.
ssehoony의 이미지

vsnprintf의 리턴값을 이용해 이 문제를 해결할 수 있습니다.
다음은 제가 로그용으로 만든 코드의 일부입니다. 도움이 되길 바랍니다.

    char buf_data[256];
    char* data = buf_data;
    int data_size = sizeof(buf_data);
 
    ....
 
    va_start(argptr, fmt);
    ret = vsnprintf(data, data_size, fmt, argptr);
    ++ret;
    va_end(argptr);
 
    if(ret > sizeof(buf_data))
    {
        data = malloc(ret);
        data_size = ret;
        va_start(argptr, fmt);
        vsnprintf(data, data_size, fmt, argptr);
        va_end(argptr);
    }
 
    ....
 
    if(data != buf_data)
        free(data);
superkkt의 이미지

vsnprintf의 리턴값을 이용해서 해결했습니다. ^^ 답변주신 분들 모두 감사드립니다~

======================
BLOG : http://superkkt.com

======================
BLOG : http://superkkt.com

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.