I am using snprintf to concatenate a string to a char array:
char buf[20] = "";
snprintf(buf, sizeof buf, "%s%s", buf, "foo");
printf("%s\n", buf);
snprintf(buf, sizeof buf, "%s%s", buf, " bar");
printf("%s\n", buf);
The problem is the second concatenation to buf
instead of adding "bar"
, replaces "foo"
with it. The output is like:
foo
bar
The first %s
should keep buf
(which in this case holds "foo"
) there. And the second %s
should attach "bar"
to it. Right?
What am I doing wrong?
If you must use snprintf , you will need to create a separate pointer to keep track of the end of the string. This pointer will be the first argument that you pass to snprintf . Your current code always uses buf , which means that it will always print to the beginning of that array.
The sscanf () function and the sprintf () function are like the two sides of a coin. You can now use the sprintf() function to reassemble the string. You can use the same char array stringa- its previous value gets overwritten.
The snprintf function is similar to sprintf , except that the size argument specifies the maximum number of characters to produce. The trailing null character is counted towards this limit, so you should allocate at least size characters for the string s .
The concat() method joins two or more strings. The concat() method does not change the existing strings. The concat() method returns a new string.
You're violating the restrict
contract on snprintf
, which states that no other argument can overlap the buffer.
Copying the input into itself is a waste of effort anyway. snprintf
returns the number of characters which formatting would require, so take advantage of this for appending:
char buf[20] = "";
char *cur = buf, * const end = buf + sizeof buf;
cur += snprintf(cur, end-cur, "%s", "foo");
printf("%s\n", buf);
if (cur < end) {
cur += snprintf(cur, end-cur, "%s", " bar");
}
printf("%s\n", buf);
While the accepted answer is alright, the better (in my opinion) answer is that concatenating strings is wrong. You should construct the entire output in a single call to snprintf
. That's the whole point of using formatted output functions, and it's a lot more efficient and safer than doing pointer arithmetic and multiple calls. For example:
snprintf(buf, sizeof buf, "%s%s%s", str_a, str_b, str_c);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With