Sprintf有关格式化的警告

时间:2017-07-18 06:25:15

标签: c printf c99

我在c中遇到sprintf格式问题。无论以何种方式格式化数据,编译器都会发现另一个问题。首先,请考虑以下代码:

#include <stdio.h>
#include <stdint.h>

int main(void) 
{
    char text[100];
    uint8_t hours = 1, minutes = 10, seconds = 20;
    int32_t milisec = 300;

    sprintf(text, "[%02u:%02u:%02u.%03i]", hours, minutes, seconds, milisec);
    printf("%s", text);

    return 0;
}

编译器抱怨:

warning: format '%u' expects argument of type 'unsigned int', but argument 3 has type 'uint32_t {aka long unsigned int}' [-Wformat=]
warning: format '%u' expects argument of type 'unsigned int', but argument 4 has type 'uint32_t {aka long unsigned int}' [-Wformat=]
warning: format '%u' expects argument of type 'unsigned int', but argument 5 has type 'uint32_t {aka long unsigned int}' [-Wformat=]
warning: format '%i' expects argument of type 'int', but argument 6 has type 'int32_t {aka long int}' [-Wformat=]

如果我将%u更改为%lu,我会:

warning: format '%lu' expects argument of type 'long unsigned int', but argument 3 has type 'int' [-Wformat=]

2 个答案:

答案 0 :(得分:4)

您需要为这些类型使用适当的formatting macro。例如

#include <inttypes.h>

uint32_t hours = 1, minutes = 10, seconds = 20;
int32_t milisec = 300;

sprintf(text, "[%02" PRIu32 ":%02" PRIu32 ":%02" PRIu32 ".%03" PRId32 "]",
        hours, minutes, seconds, milisec);

在上面的片段PRIu32用于打印十进制uint32_tPRId32打印int32_t

另一种选择是仅使用int/unsigned来表示所有这些值,并希望32767/65535小时足以满足所有人的需求。

答案 1 :(得分:2)

标头<inttypes.h>提供PRIu8PRIi32等宏,它们是uint8_tint32_t等标准整数类型的格式字符串片段。优点是这些宏是可移植的,并且包含正确的格式说明符,即使使用不同的基本类型来实现这些整数类型。