2015-09-07 4 views
1

Есть ли эквивалент va_list snprintf, который принимает va_list переменных аргументов? Я пытаюсь выполнить две функции:Формирование строки C с помощью va_list

char * __HYP format_cstring(const char * format, ...); 
chat * __HYP format_cstringv(const char * format, var_list args); 

Но я не знаю, как применить snprintf к этой ситуации. Что-то вроде этого (обратите внимание на знаки вопроса):

char * __HYP format_cstring(const char * format, ...) 
{ 
    int size = snprintf(NULL, 0, format, ??); 
    char * buffer = (char *)malloc(size * sizeof(char)); 

    if (snprintf(buffer, size, format, ??) < 0) { 

    free(buffer); 
    return NULL; 
    } 

    return buffer; 
} 

А как насчет его format_cstringv коллеги?

+2

Не бросайте 'malloc'; 'sizeof (char)' равен 1 по определению. – melpomene

+0

Например, http://port70.net/~nsz/c/c11/n1570.html#7.21.6.12. Уходит ли Google? – Olaf

+2

Вы не можете. См. 'Vsnprintf'. http://www.cplusplus.com/reference/cstdio/vsnprintf/ – Gene

ответ

-2

Вас интересует формат% r, который существует с 1980 года по UNOS и DECUS.

См: http://austingroupbugs.net/view.php?id=800

Существует 30 + лет реализации в libschily см: `http://sourceforge.net/projects/schilytools/files/ и пока еще не опубликованы реализации в качестве дополнения к LibC на Solaris.

% r разрешает любую функцию на основе printf(), которую вызывается с помощью функции-обертки, которая может предложить полный набор функций printf().

% г принимает два аргумента:

1) строка формата

2) параметр типа va_list

Она нуждается в аксессуар к vararg макросов под названием: va_arg_list() аналогичен и для того же самого почему Sun/Solaris должны были ввести va_copy() в начале 1990-х годов, чтобы реализовать %n$.

BTW: Обсуждались проблемы% r в usenet около 1985 года, но люди, которые обсуждали эту функцию в то время, полагали, что она не переносима. Мой код был протестирован на всех существующих типах ЦП, и мне интересно, чтобы это было добавлено к стандарту ISO C.

Вот несколько примеров кода:

int 
error(const char *fmt, ...) 
{ 
     va_list args; 
     int  ret; 

     va_start(args, fmt); 
     ret = js_fprintf(stderr, "%r", fmt, args); 
     va_end(args); 
     return (ret); 
} 
1

Вот как я в конечном итоге делает это:

// .h 
char * sformat(const char * format, ...) __attribute__((format (printf, 1, 2))); 
char * vsformat(const char * format, va_list args) __attribute__((format (printf, 1, 0))); 

И реализации:

char * __HYP sformat(const char * format, ...) 
{ 
    char * buffer; 

    va_list args; 
    va_start(args, format); 
    buffer = __HYP vsformat(format, args); 
    va_end(args); 

    return buffer; 
} 

char * __HYP vsformat(const char * format, va_list args) 
{ 
#pragma GCC diagnostic push 
#pragma GCC diagnostic ignored "-Wformat-nonliteral" 

    int size = vsnprintf(NULL, 0, format, args); 

    if (size <= 0) { 
    return NULL; 
    } 

    char * buffer = new char[size + 1]; 

    if (buffer == NULL) { 
    return NULL; 
    } 

    if (vsnprintf(buffer, static_cast<size_t>(size), format, args) <= 0) { 

    free(buffer); 
    return NULL; 
    } 

#pragma GCC diagnostic pop 

    return buffer; 
} 

Я выяснить, как забыл, что я про C++, через несколько лет, не касаясь его.

Смежные вопросы