sprintf很有趣

时间:2013-06-12 12:12:56

标签: c linux windows printf

我对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);

6 个答案:

答案 0 :(得分:9)

%llu中使用task_id的{​​{1}}格式字符串,如下所示:

sprintf()

编辑:由于@ Simonc建议使用它更好:sprintf(sql, "%llu, %u", task_id, app_id); // ^ // for: long long unsigned int 中定义的PRIu32PRIu64宏(因为你有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字节)和00task_id的高4字节并打印64, 00

答案 3 :(得分:0)

尝试:

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

答案 4 :(得分:0)

正如已经指出的那样,uint64_t的正确格式说明符是PRIu64不是 lu,因为无法保证uint64_tlong)。

所以,你需要使用它:

#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值时看到的内容。

如果长值恰好具有相同的位数,或者该值以预期结果恰好位于正确位置的方式存储在存储器中,则可以打印正确的值,但当然,代码仍然是错误的,虽然它似乎有用。