Unexpected result in sprintf ()

Can someone help me understand what's going on?

char pcMessage[255];
iMsgAllocatedLength=255;
unsigned long long ullRecordID = 135290303ULL;
sprintf_s(pcMsg, iMsgAllocatedLength, "%08X;%llu", ullRecordID, ullRecordID);

      

Gives the following output:

08105DBF ; 581067426850930688;

While

sprintf_s(pcMsg, iMsgAllocatedLength, "%010llu;%08X;", ullRecordID, ullRecordID);

      

Gives the expected result

0135290303 08105DBF

Note that I just reversed the order, and also note that 581067426850930688 08105DBF 00000000

Please help me understand.

+3


source to share


3 answers


Printing unsigned long long

using a format specifier %X

is undefined behavior because it sprintf

expects unsigned int

for %X

. It gives correct results when you switch the specifiers for an unfortunate match. The behavior on different platforms may not be the same.

Use %llX

values ​​to print:



sprintf_s(pcMsg, iMsgAllocatedLength, "%08llX;%llu", ullRecordID, ullRecordID); 

      

+8


source


You are passing a specifier unsigned long long

for "%x"

that expects unsigned int

. So your code includes undefined behavior. Nobody knows what will happen in this case, and you cannot count on anything. It might work, or it might crash, or maybe print some of what you expect, or print garbage or whatever.



+4


source


Without a length modifier, the directive %X

expects the corresponding argument to be of type unsigned int

. In your case, the relevant argument is in fact unsigned long long int

, which is unlikely to be - and in your case, apparently not - of the same type. You want to use instead %llX

:

sprintf_s(pcMsg, iMsgAllocatedLength, "%08llX;%llu", ullRecordID, ullRecordID);

      

Note that the version that prints the expected output is also wrong - you're just in luck.

+3


source







All Articles