You don't need malloc
for that tiny amount of memory, a char str[5]
would
also do the job in this case. Also bear in mind that you shouldn't cast malloc
. And sizeof(char)
is always 1,
so you can omit that as well. You should also always check the return value of
malloc
:
char *str = malloc(5);
if(str == NULL)
{
// error handling
}
And don't forget to free the memory.
But I'm digressing now. The problem in your code problem is that
str[2] = 'e';
is overwriting the 4 in "h34"
. That's why the output is h3e
. After the
sprintf
call the memory looks like this:
index 0 1 2 3 4
+-----+-----+-----+------+-----+
| 'h' | '3' | '4' | '\0' | ??? |
+-----+-----+-----+------+-----+
The correct index is 3
, not 2:
char str[5];
str[0] = 'h';
sprintf(&str[1], "%d", 34);
str[3] = 'e';
str[4] = '\0'; // making sure to terminate string
puts(str); // output is h34e
If you append a character, you must not forget to set the
'\0'
-terminating byte. That's what I'm doing in str[4] = '\0'
. In your
example you were "lucky" because you didn't overwrite the '\0'
-terminating
byte, so the string was still terminated correctly.
Also snprintf
takes the length as well, without the length you should use
sprintf
. In this case you can use sprintf
because you know the size of the
buffer and the length of the number, you know that you are not going to write
beyond the limits, that's why in this case it's OK to use sprintf
instead of
snprintf
.
But of course you can do that in two lines of code:
char str[5];
sprintf(str, "h%de", 34);
But I also like your original code because it forces you to think about how to access
elements of the array with indices and how strings are stored in memory. As an exercise this is good. For more serious projects, I wouldn't create strings in such a way. I'd use the one-liner solution.