Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

snprintf for string concatenation

Tags:

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?

like image 235
Jermin Bazazian Avatar asked Aug 22 '12 01:08

Jermin Bazazian


People also ask

How do I concatenate strings using Snprintf?

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.

Does Snprintf overwrite or append?

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.

What is the difference between Sprintf and Snprintf?

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 .

Can you concatenate strings in JavaScript?

The concat() method joins two or more strings. The concat() method does not change the existing strings. The concat() method returns a new string.


2 Answers

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);
like image 137
Ben Voigt Avatar answered Sep 17 '22 15:09

Ben Voigt


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);
like image 27
R.. GitHub STOP HELPING ICE Avatar answered Sep 19 '22 15:09

R.. GitHub STOP HELPING ICE