22

我有以下代码。sprintf 中第二个 %d 的输出始终显示为零。我想我指定了错误的说明符。任何人都可以帮助我获得具有正确值的写入字符串。这必须在posix标准中实现。感谢您的投入

void main() {
    unsigned _int64 dbFileSize = 99;
    unsigned _int64 fileSize = 100;
    char buf[128];
    memset(buf, 0x00, 128);
    sprintf(buf, "\nOD DB File Size = %d bytes \t XML file size = %d bytes", fileSize, dbFileSize);
    printf("The string is %s ", buf);
    }

输出:

The string is
OD DB File Size = 100 bytes      XML file size = 0 bytes 
4

4 回答 4

18

我不知道 POSIX 对此有什么看法,但核心 C99 很好地处理了这一点:

#include <stdio.h>
#include <inttypes.h>

int main(void) {
    uint64_t dbFileSize = 99;
    uint64_t fileSize = 100;
    char buf[128];
    memset(buf, 0x00, 128);
    sprintf( buf, "\nOD DB File Size = %" PRIu64 " bytes \t"
                  " XML file size = %" PRIu64 " bytes\n"
                  , fileSize, dbFileSize );
    printf( "The string is %s\n", buf );
}

如果您的编译器不符合 C99,请使用其他编译器。(是的,我在看着你,Visual Studio。)

PS:如果您担心便携性,请不要使用%lld. 那是为了long long,但不能保证long long实际上与_int64(POSIX) 或int64_t(C99) 相同。

编辑: Mea culpa - 我或多或少无脑地“搜索和替换” _int64,而int64_t没有真正看我在做什么。感谢您指出它是uint64_t,不是的评论unsigned int64_t。已更正。

于 2011-02-28T10:44:33.017 回答
17

您需要在Visual C++中使用%I64u 。

但是,在大多数 C/C++ 编译器上,64 位整数是 long long。因此,采用long long并使用%llu

于 2011-02-28T10:41:32.020 回答
11

如果您正在寻找可移植的解决方案,使用<inttypes.h>. 您可能需要定义__STDC_FORMAT_MACROS以使这些在 C++ 中可用。

于 2011-02-28T10:49:13.773 回答
0

我会使用sprintf_swith %dzand uint64_t,当我尝试它并发现 %dz(无符号整数的格式说明符)适用于 uint32_t 时,会立即发现我是个白痴,这是个好消息,但它不适用于uint64_t。虽然我认为 Keith Thompson 在使用 PRIu64 方面已经充分回答了这个问题,但我要做的一个改变是使用缓冲区溢出安全版本 sprintf_s 和 printf_s,另一个是在声明 char 时(直接)初始化它,如Jens Gustedt 建议;

#include <stdio.h>
#include <inttypes.h>

uint64_t dbFileSize = 99;
uint64_t fileSize = 100;
char buf[128]{ 0 };
sprintf_s(buf, "\nOD DB File Size = %" PRIu64 " bytes \t XML file size = %" PRIu64 " bytes\n", fileSize, dbFileSize);
printf_s("The string is %s ", buf);
于 2022-01-17T21:45:55.950 回答