我对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"
已定义:I64u
,Windows不支持。所以我可以这样写:
sprintf(sql, "%I64u, %I32u", task_id, app_id);
答案 0 :(得分:9)
在%llu
中使用task_id
的{{1}}格式字符串,如下所示:
sprintf()
编辑:由于@ Simonc建议使用它更好:sprintf(sql, "%llu, %u", task_id, app_id);
// ^
// for: long long unsigned int
中定义的PRIu32
和PRIu64
宏(因为你有Linux标记)确实如下:
<inttypes.h>
答案 1 :(得分:3)
格式字符串%lu
不适用于32位计算机,其中64位变量为long long
。
使用%llu
代替64位:
#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;
}
答案 2 :(得分:1)
只是添加其他人说的话:
给予
sprintf(sql, "%u, %u", app_id, task_id);
而不是
sprintf(sql, "%u, %u", task_id, app_id);
给出输出32, 64
!!
无需担心!原因如下:
在推送task_id
(作为app_id
的参数)之前,sprintf
被推送到堆栈(先高4个字节,低4个字节)。但是当sprintf
转到参数时,它会从堆栈中弹出4个字节+4个字节,因为格式中指定了两个%u。因此它需要task_id
的低4字节并将其打印为unsigned int
。
给出sprintf(sql, "%u, %u", task_id, app_id);
时会发生同样的情况。
app_id
,然后推出task_id
。但是当sprintf读取时,它弹出两个4字节,64
(task_id的低4字节)和00
(task_id
的高4字节并打印64, 00
。
答案 3 :(得分:0)
尝试:
sprintf(sql, "%lu, %u", task_id, app_id);
答案 4 :(得分:0)
正如已经指出的那样,uint64_t
的正确格式说明符是PRIu64
(不是 lu
,因为无法保证uint64_t
是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);
答案 5 :(得分:-1)
格式说明符错误。 printf
函数不知道传递给它的参数类型,它只能从格式说明符中推断出来。因此,当您向其传递一个64位整数,并告诉函数您只传递了一个长(32位)时,它只传入64位值的一半。根据体系结构,可能会打印正确的结果。原因是数字如何存储在内存中以及printf函数在读取long
值时看到的内容。
如果长值恰好具有相同的位数,或者该值以预期结果恰好位于正确位置的方式存储在存储器中,则可以打印正确的值,但当然,代码仍然是错误的,虽然它似乎有用。