Для вывода отформатированного отладочного вывода я написал обертку для vsfprint
. Теперь я хотел выделить достаточно памяти для выходного буфера вместо того, чтобы просто требовать размер случайного большого буфера (это небольшая встроенная платформа (ESP8266)). Для этого я повторяю аргументы переменной до тех пор, пока не будет найден NULL.C variadic wrapper
Это прекрасно работает при условии, что я не забудьте добавить параметр (char *)NULL
к каждому звонку. Итак, я подумал, давайте создать еще одну оболочку, функцию, которая просто ретранслирует все аргументы и добавляет параметр (char *) NULL
:
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h> // malloc
void write_log(const char *format, ...) {
char* buffdyn;
va_list args;
// CALC. MEMORY
size_t len;
char *p;
if(format == NULL)
return;
len = strlen(format);
va_start(args, format);
while((p = va_arg(args, char *)) != NULL)
len += strlen(p);
va_end(args);
// END CALC. MEMORY
// ALLOCATE MEMORY
buffdyn = malloc(len + 1); /* +1 for trailing \0 */
if(buffdyn == NULL) {
printf("Not enough memory to process message.");
return;
}
va_start(args, format);
//vsnprintf = Write formatted data from variable argument list to sized buffer
vsnprintf(buffdyn, len, format, args);
va_end(args);
printf("%s\r\n",buffdyn);
free(buffdyn);
}
void write_log_wrapper(const char *format, ...) {
va_list arg;
va_start(arg, format);
write_log(format,arg,(char *)NULL);
va_end(arg);
}
int main()
{
const char* sDeviceName = "TEST123";
const char* sFiller1 = "12345678";
write_log_wrapper("Welcome to %s%s", sDeviceName,sFiller1);
write_log("Welcome to %s%s", sDeviceName,sFiller1, (char *)NULL);
return 0;
}
Вызов функции write_log()
непосредственно работает нормально (если вы не забыли параметр NULL). Вызов функции write_log_wrapper()
отобразит только первый параметр, а затем добавит к выходу «(nu» (мусор?)).
Что я делаю неправильно? Является ли это хорошим способом приблизиться к тому, к чему я стремлюсь делать в первую очередь?
спасибо.
Если вы намереваетесь написать его на 'stdout', почему бы вам просто не использовать' vprintf'? То же самое следует, если вы хотите записать в файл (используйте 'vfprintf'). Тогда в вашем коде вообще нет выделения буфера, и вам не нужно разбираться в том, сколько аргументов или сколько буфера. –
Вы игнорируете возможность того, что один из переданных аргументов не является строкой, завершенной NUL, переданной через 'char *'. Что делать, если вы получаете 'int' или' double'? –
... или NULL с% p –