спецификаторы формата printf для uint32 t и размера t

у меня есть следующие

size_t   i = 0;
uint32_t k = 0;

printf("i [ %lu ] k [ %u ]\n", i, k);

Я получаю следующее предупреждение при компиляции:

format ‘%lu’ expects type ‘long unsigned int’, but argument has type ‘uint32_t’

когда я запустил это с помощью шины, я получил следующее:

Format argument 1 to printf (%u) expects unsigned int gets size_t: k

большое спасибо за любые советы,

4 ответов


звучит так, как будто вы ожидаете size_t чтобы быть таким же, как unsigned long (возможно, 64 бита), когда на самом деле это unsigned int (32 бита). Попробуйте использовать %zu в обоих случаях.

Я не совсем уверен, хотя.


попробовать

#include <inttypes.h>
...

printf("i [ %zu ] k [ %"PRIu32" ]\n", i, k);

на z представляет целое число длины, такое же, как size_t и PRIu32 макрос определено в заголовке C99 inttypes.h, представляет 32-разрядное целое число без знака.


все, что нужно, это то, что спецификаторы формата и типы согласуются, и вы всегда можете бросить, чтобы это было правдой. long не менее 32 бит, так что %lu вместе с (unsigned long)k всегда правильно:

uint32_t k;
printf("%lu\n", (unsigned long)k);

size_t сложнее, поэтому %zu был добавлен в C99. Если вы не можете использовать это, то относитесь к нему так же, как k (long самый большой тип в C89,size_t вряд ли будет больше).

size_t sz;
printf("%zu\n", sz);  /* C99 version */
printf("%lu\n", (unsigned long)sz);  /* common C89 version */

если вы не получите формат спецификаторы, правильные для передаваемого типа, затем printf будет делать эквивалент читаешь слишком много или слишком мало памяти из массива. Пока вы используете явные приведения для сопоставления типов, он переносим.


если вы не хотите использовать макросы PRI*, другой подход для печати любой целочисленный тип должен привести к intmax_t или uintmax_t и использовать "%jd" или %ju, соответственно. Это особенно полезно для типов POSIX (или других ОС), которые не имеют определенных макросов PRI*, например off_t.