sprintf() 中的意外结果

Unexpected result in sprintf()

有人可以帮助我了解发生了什么吗?

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

给出以下结果

08105DBF;581067426850930688;

同时

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

给出了预期的结果

0135290303;08105DBF

请注意我只是颠倒了顺序,还要注意
581067426850930688 是 08105DBF00000000

请帮我理解。

您为 "%x" 说明符传递了 unsigned long long,它需要 unsigned int。因此,您的代码涉及未定义的行为。没有人知道在那种情况下会发生什么,你不能指望任何事情。它可能会工作,也可能会崩溃,或者可能会打印出您期望的部分内容,或者打印垃圾,或者其他任何东西。

使用 %X 格式说明符打印 unsigned long long 是未定义的行为,因为 sprintf 期望 %Xunsigned int。当您因不幸的巧合而切换说明符时,它会产生正确的结果。不同平台的行为可能不一样。

使用%llX打印值:

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

没有任何长度修饰符,%X 指令期望相应的参数为 unsigned int 类型。在你的例子中,相应的参数实际上是一个 unsigned long long int,这不太可能——在你的例子中显然不是——相同的类型。您想使用 %llX 代替:

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

请注意,打印预期输出的版本也是错误的——您只是走运而已。