问题
I am coding under Arduino and I would like to develop serial print formatting function, so I am trying to use sprintf
of unknown sized buffer. Basically, we can avoid talking about Arduino and its serial output and consider writing text to a buffer and then printing it by using printf
. I've tried this one:
#include <stdio.h>
#include <stdarg.h>
void printf0( const char* format, ... ) {
va_list args;
va_start(args, format);
vprintf(format, args);
va_end( args );
}
void printf1(const char* format,...) {
va_list args;
va_start(args, format);
char buf[vsnprintf(NULL, 0, format, args)];
sprintf(buf, format, args);
printf(buf);
va_end(args);
}
int main()
{
printf0("Hello, %d!\n", 15);
printf1("Hello, %d!\n", 15);
return 0;
}
printf0
function is an accurate example I found here. My tries is function printf1
, which produces unpredictable number. Example output of the above programme is:
Hello, 15!
Hello, 860799736!
回答1:
args
is a va_list
, so you cannot call sprintf
with it. You have to use vsprintf
or vsnprintf
:
sprintf(buf, format, args);
should be
vsnprintf(buf, sizeof buf, format, args);
Also you should add 1 to the size of buf
for the 0-terminator of the string:
char buf[vsnprintf(NULL, 0, format, args) + 1];
It seems that the first call to vsnprintf
changes args
, so you have to add
va_end(args);
va_start(args, format);
between the 2 calls: http://ideone.com/5YI4Or
It seems that the first call to vsnprintf
changes args
, but you should not call va_start
twice. You should use va_copy
instead, so add
va_list args2;
va_copy(args2, args);
after initializing args
. Also do not forget to call va_end(args2);
too:
http://ideone.com/loTRNL
Link to the va_copy
man page: https://linux.die.net/man/3/va_copy
来源:https://stackoverflow.com/questions/42131753/wrapper-for-printf