C语言中printf字符串格式的奇怪行为

时间:2013-06-03 14:27:31

标签: c printf string-formatting tinyos nesc

根据我的理解,我在nesC中有以下功能,与C基本相同!

event void AdaptiveSampling.dataAvailable(error_t result, float val, bool isRealData)
{       
    if(result == SUCCESS)
    {
        //converting raw ADC to centigrade
        centiGrade = -39.60 + 0.01 * val;                       

        //printing the value to serial port
        if(isRealData)
        {
            printf("REAL: Temperature is: %d CentiGrade\r\n", centiGrade); //line 91
            printf("%d,R,%d,%d\r\n", _counter, val, centiGrade); //line 92
        }   
        else
        {
            printf("PEDICTED: Temperature is: %d CentiGrade\r\n", centiGrade); //line 96
            printf("%d,P,%d,%d\r\n", _counter, val, centiGrade); //line 97
        }   
        _counter++;     
    }
    else
    {
        printf("Error reading sensor!");
    }
}

而且,在我的代码的顶部,我已经定义了这些变量:

uint32_t _counter;
uint16_t centiGrade;

这是我在构建期间收到的警告:

AdaptiveSamplingC.nc:92:11: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘uint32_t’ [-Wformat]
AdaptiveSamplingC.nc:92:11: warning: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘float’ [-Wformat]
AdaptiveSamplingC.nc:97:11: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘uint32_t’ [-Wformat]
AdaptiveSamplingC.nc:97:11: warning: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘float’ [-Wformat]

以下是屏幕输出的示例:

PEDICTED: Temperature is: 26 CentiGrade
291,P,0,-3402
REAL: Temperature is: 26 CentiGrade
292,R,0,4096
PEDICTED: Temperature is: 26 CentiGrade
293,P,0,-1495

问题:

在第91行,我希望看到温度值是浮动的...我的意思是像26.25这样的东西...但由于某种原因它打印出整数。我试图将%d更改为%f,但它没有帮助,因为您看到第92行和第97行的输出几乎已损坏,原因是我无法弄清楚!

此外,我没有解释为什么第92行和第97行表现得那么奇怪,为什么它们在构建期间会有警告。

请您告诉我该怎么做才能改善?

3 个答案:

答案 0 :(得分:1)

您的问题是未定义的行为,这就是您收到警告的原因。警告表明实际上是错误的

printf是一个可变函数,因此它需要一些有关参数类型的信息。这是格式说明符的工作(例如%d)。

%d告诉printf期望一个int类型的参数,您的警告消息告诉您:警告:格式%d需要int类型的参数1}}

但是,您提供的类型不是int。它们是uint32_tfloat,您的警告消息也告诉您:但参数2的类型为uint32_t [-Wformat] 但是参数3的类型为float [-Wformat]

有很多解决方案。最好的是使用正确的格式说明符!(duh)。 "%d"int"%"PRIu32uint32_t"%f"doublefloat被提升为uint32_t。对于unsigned long,您可以转换为"%lu"并使用{{1}}进行打印。

答案 1 :(得分:0)

您正在将16位无符号整数变量与此行centiGrade = -39.60 + 0.01 * val;

上的浮点计算混合

你想要的是将centiGrade保持为浮点数并仅在打印时将其转换为int。

答案 2 :(得分:0)

警告说全部。您提供了错误的格式字符串。 (请记住:警告是伪装的错误。总是修复它们。)

对于无符号整数使用%u,对于浮点数使用%f。您甚至可以提供有关如何格式化浮点数的额外信息。例如,%.2f会在小数点后面给出2个数字。

还有:

centiGrade = -39.60 + 0.01 * val;  

错了。您无法为uint16_t指定浮点数。只需将centiGrade设为float,您就可以了。

有关说明符的更多信息,请访问:http://www.cplusplus.com/reference/cstdio/printf/