Re: sprintf and sprintf_s
Alex Blekhman wrote:
"Ben Voigt [C++ MVP]" wrote:
sprintf(&u[8], "%u", 0x87654321)
BTW, 8 characters are not enough to print 0x12345678 in
decimal. The string will be: "305419896", i.e. 9 characters +
terminating nul.
What does this "8 characters are not enough" have to do with any
of the questions or posted code?
Obviously it has to do with the previous post about 64-bit
integers. The OP wants to print 64-bit number into a string
buffer. He does it in two steps: prints first half of a number,
then prints second half of a number. Like this:
union utype
{
unsigned long long ull;
unsigned long ul[2];
};
utype ut;
ut.ull = 0x1234567887654321;
char u[100];
sprintf(u, "%u", ut.ul[1]);
sprintf(&u[8], "%u", ut.ul[0]);
The expectation is that the `u' buffer will contain the string:
"1234567887654321". I think now you can see the bug. He prints it
in decimal, so first half of a 64-bit number will take more than 8
characters: "305419896". When second half of a number is printed
starting from 7th position, then the last character in the string
is overwritten.
That's all.
Ok, that makes more sense. I can't find that other post at the moment, but
I did see it, I just didn't make the connection that it was the same poster
and that there were two numbers being concatenated (of course string
concatenation of numbers which are expressed in decimal and 2^32 apart in
place value doesn't make any sense either, people recommended to him to use
%X).
In any case, this can be solved safely by:
template <size_t N>
size_t sprintf_offset( char (&output)[N], size_t offset, const char* format,
.... )
{
if (offset > N)
return 0;
va_arg junk...
return vsprintf_s(&output[offset], N - offset, format, args);
}
and then
sprintf(u, "%x", ut.ul[1]);
sprintf_offset(u, 8, "%x", ut.ul[0]);
Alex