Reputation: 136
I am building commands with snprintf()
that i want to execute with system()
. I noticed that the last character is missing when i use %s
at the end of the format string but when i am adding an extra space after the %s
it works as i would expect. Why does this happen? I think i am missing something. I appreciate your help!
Here is an minimal example:
#define INTERFACE "can0"
int size;
char *command = NULL;
size = snprintf(command, 0, "/sbin/ifdown %s", INTERFACE);
command = malloc(size);
snprintf(command, size, "/sbin/ifdown %s", INTERFACE);
Upvotes: 1
Views: 1240
Reputation: 16726
en.cppreference says (emphasize is mine)
int snprintf( char *restrict buffer, size_t bufsz, const char *restrict format, ... ); (4)
- Writes the results to a character string buffer. At most bufsz - 1 characters are written. The resulting character string will be terminated with a null character, unless bufsz is zero. If bufsz is zero, nothing is written and buffer may be a null pointer, however the return value (number of bytes that would be written not including the null terminator) is still calculated and returned.
So your first call returns the number of characters that would be written excluding the terminating null character. Your second call to snprintf
says that size
characters should be written including the terminating null character.
So the fix should be to allocate a bigger buffer and to pass size+1
in the second call.
command = malloc(size+1);
snprintf(command, size+1, "/sbin/ifdown %s", INTERFACE);
You don't show the code with the extra space. But I guess you have added it to the first call of snprintf
and maybe also to the second call. In that case your first snprintf
returns a size
that is one higher. The second snprintf
cannot write the additional space, but with the higher size
it can now write the string as you expect it.
Upvotes: 2
Reputation: 72479
snprintf
returns the number of characters printed not including the null terminator. Therefore when you pass that size back to snprintf
it figures out that your buffer is one char short. Fix it as follows:
size = snprintf(command, 0, "/sbin/ifdown %s", INTERFACE);
command = malloc(size+1);
snprintf(command, size+1, "/sbin/ifdown %s", INTERFACE);
Upvotes: 3