views:

3108

answers:

5

Is there a way to use the C sprintf() function without it adding a '\0' character at the end of its output? I need to write formatted text in the middle of a fixed width string.

+9  A: 

There is no way to tell sprintf() not to write a trailing null. What you can do is use sprintf() to write to a temporary string, and then something like strncpy() to copy only the bytes that you want.

Greg Hewgill
bleh, I was afraid of that. thanks.
zaratustra
Or use memmove() or perhaps memcpy() rather than strncpy().
Jonathan Leffler
snprintf, anyone...?
Roddy
Roddy: The snprintf function always null terminates its output. If you pass a size n to snprintf, it will write at most n-1 characters followed by a trailing '\0'.
Greg Hewgill
@Greg - it appears implementation dependent...
Roddy
+4  A: 

sprintf returns the length of the string written (not including the null terminal), you could use that to know where the null terminal was, and change the null terminal character to something else (ie a space). That would be more efficient than using strncpy.

 unsigned int len = sprintf(str, ...);
 str[len] = '<your char here>';
Doug T.
+2  A: 

You could also use your fixed width string as a format string like this:

char my_fixed_width_string_format[] = "need 10 chars starting here: %10s";
char my_fixed_width_string[40];
char string_to_print[] = "abcdefghijklmnop";
sprintf(my_fixed_width_string, my_fixed_width_string_format, string_to_print;
printf(my_fixed_width_string);

should yield

need 10 chars starting here: abcdefghij

Nathan Fellman
This is probably the best way to do it.
pjc50
+1  A: 

You can't do this with sprintf(), but you may be able to with snprintf(), depending on your platform.

You need to know how many characters you are replacing (but as you're putting them into the middle of a string, you probably know that anyway).

This works because some implementations of snprintf() do NOT guarantee that a terminating character is written - presumably for compatibility with functions like stncpy().

char message[32] = "Hello 123, it's good to see you.";

snprintf(&message[6],3,"Joe");

After this, "123" is replaced with "Joe".

On implementations where snprintf() guarantees null termination even if the string is truncated, this won't work. So if code portability is a concern, you should avoid this.

Most Windows-based versions of snprintf() exhibit this behaviour.

But, MacOS and BSD (and maybe linux) appear to always null-terminate.

Roddy
The snprintf function always null terminates its output. After running the above code, message contains "Hello Jo".
Greg Hewgill
@Greg. You're almost right... I've updated answer to reflect implementation dependence.
Roddy
Wow, I never knew that differed across platforms, thanks for that.
Greg Hewgill
Does anybody have any idea what the POSIX and/or C99 specifications dictate?
Tommy
A: 

look here: http://en.wikipedia.org/wiki/Printf

printf("%.*s", 3, "abcdef") will result in "abc" being printed

nir