I\'m so confused with sprintf that a funny problem with different platfrom. Code :
int main ()
{
char sql[1024];
uint32_t app_id = 32;
uint64_t
Just adding to what others have said:
Giving
sprintf(sql, "%u, %u", app_id, task_id);
instead of
sprintf(sql, "%u, %u", task_id, app_id);
gives an output 32, 64
!!
No need to worry! Here is why:
task_id
is pushed to stack (higher 4 bytes first and lower 4 bytes second) before pushing app_id
(as arguments to sprintf
). But when sprintf
goes to take arguments, it pops 4 bytes + 4 bytes from stack, as two %u are specified in the format. So it takes the lower 4 bytes of task_id
and prints it as unsigned int
.
The same happens when sprintf(sql, "%u, %u", task_id, app_id);
is given.
app_id
is pushed first and task_id
next. But when sprintf reads, it pops two 4 bytes, 64
(the lower 4 bytes of task_id) and 00
(higher 4 byte of task_id
and prints 64, 00
.
As has been pointed out, the proper formatting specifier for uint64_t
is PRIu64
(not lu
, since there's no guarantee that uint64_t
is long
).
So, you need to use that:
#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);
Format string %lu
won't work on 32-bit machines, where a 64-bit variable is long long
.
Use %llu
for 64-bit instead:
#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;
}
Try:
sprintf(sql, "%lu, %u", task_id, app_id);
Use %llu
format string for task_id
in sprintf()
as follows:
sprintf(sql, "%llu, %u", task_id, app_id);
// ^
// for: long long unsigned int
Edit: As @Simonc suggested its better to use: PRIu32
and PRIu64
macros defined in <inttypes.h>
(as you have Linux tag) do like:
sprintf(sql, "%"PRIu64", %"PRIu32"", task_id, app_id);
// ^ ^
// for: uint64_t uint32_t
The format specifier is wrong. The printf
function doesn't know what kind of parameters are passed to it, it can only deduce this from the format specifiers. So when you pass a 64bit integer to it, and tell the function that you passed only a long (32bit) then it takes only half of the 64 bit value passed in. Depending on the architecture, the correct result might be printed or not. The reason is how the number is stored in memory and what the printf function sees when it reads the long
value.
If the long value happens to have the same number of bits or the value is stored in memory in such a way that the expected result happens to be in the right place, the correct value could be printed, but of course, the code would still be wrong, though it appears to work.