6

我对 sprintf 感到很困惑,以至于不同平台的一个有趣问题。代码 :

int main () 
{
    char sql[1024];
    uint32_t app_id = 32;
    uint64_t task_id = 64;
    sprintf(sql, "%u, %u", task_id, app_id);
    printf ("%s\n", sql);
    return 0;
}

控制台中的结果(MSVC2010 调试/发布):64, 0

但是控制台中的代码相同(CentOS64 gcc4.4.6):64、32

任何人都会帮助我,tks!

- - - - - - -更新 - - - - - - - - - - - - -

多谢你们。我读过这篇文章:sprintf for unsigned _int64

实际上,PRIu64"inttypes.h"定义:I64uWindows 上不支持。所以我可以这样写:

sprintf(sql, "%I64u, %I32u", task_id, app_id);
4

6 回答 6

10

对in使用%llu格式字符串,如下所示:task_idsprintf()

sprintf(sql, "%llu, %u", task_id, app_id);
//             ^
//            for: long long unsigned int

编辑:正如@Simonc建议更好地使用:PRIu32并且PRIu64定义在<inttypes.h>(因为你有Linux标签)中的宏确实喜欢:

sprintf(sql, "%"PRIu64", %"PRIu32"", task_id, app_id);
//               ^           ^
//       for:   uint64_t    uint32_t  
于 2013-06-12T12:15:25.483 回答
3

格式字符串%lu在 32 位机器上不起作用,其中 64 位变量是long long.

改为用于%llu64 位:

#include <stdio.h>
#include <stdlib.h>
#include <linux/types.h>
#include <stdint.h>

int main () 
{
    char sql[1024];
    uint32_t app_id = 32;
    uint64_t task_id = 64;
    sprintf(sql, "%llu, %u", task_id, app_id);
    printf ("%s\n", sql);
    return 0;
}
于 2013-06-12T12:22:50.020 回答
1

只是补充其他人所说的:

给予

sprintf(sql, "%u, %u", app_id, task_id);

代替

sprintf(sql, "%u, %u", task_id, app_id);

给出一个输出32, 64!!

不用担心!这就是为什么: task_id在推送之前被推送到堆栈(首先是高 4 个字节,然后是低 4 个字节)app_id(作为 的参数sprintf)。但是当sprintf去取参数时,它会从堆栈中弹出 4 个字节 + 4 个字节,因为格式中指定了两个 %u。所以它需要较低的 4 个字节task_id并将其打印为unsigned int.

给予时也会发生同样的情况sprintf(sql, "%u, %u", task_id, app_id);

app_id先推后推task_id。但是当 sprintf 读取时,它会弹出两个 4 字节,64(task_id 的低 4 字节)和00(高 4 字节task_id并打印64, 00.

于 2013-06-12T13:01:07.060 回答
0

尝试:

sprintf(sql, "%lu, %u", task_id, app_id);
于 2013-06-12T12:16:13.280 回答
0

正如已经指出的那样,正确的格式说明符uint64_tis PRIu64( not lu,因为不能保证uint64_tis long)。

所以,你需要使用它:

#define __STDC_FORMAT_MACROS
#include <inttypes.h>

char sql[1024];
uint32_t app_id = 32;
uint64_t task_id = 64;
sprintf(sql, "%u, %" PRIu64, app_id, task_id);
printf ("%s\n", sql);
于 2013-06-12T12:25:49.047 回答
-1

格式说明符错误。该printf函数不知道传递给它的参数是什么样的,它只能从格式说明符中推断出来。因此,当您向它传递一个 64 位整数并告诉函数您只传递了一个 long(32 位)时,它只需要传入的 64 位值的一半。根据体系结构,可能会打印或不打印正确的结果。原因是数字是如何存储在内存中的,以及 printf 函数在读取该long值时会看到什么。

如果 long 值恰好具有相同的位数,或者该值存储在内存中的方式使得预期结果恰好在正确的位置,则可以打印正确的值,但是当然,代码仍然会错了,尽管它似乎有效。

于 2013-06-12T12:20:37.097 回答