如何打印struct timeVal

时间:2013-03-18 01:42:40

标签: c sockets unix gcc gcc-warning

我的代码中有这一行

`printf("Rcvd pkt from %s:%d at <%ld.%06ld>\n", inet_ntoa(servAddr.sin_addr),  ntohs(servAddr.sin_port), timeVal.tv_sec, timeVal.tv_usec);`

这是我在编译时使用gcc的警告

`cc1: warnings being treated as errors
`client12.c: In function ‘main’:
`client12.c:131: warning: format ‘%06ld’ expects type ‘long int’, but argument 5 has type ‘__darwin_suseconds_t’
`client12.c:131: warning: format ‘%06ld’ expects type ‘long int’, but argument 5 has type ‘__darwin_suseconds_t’

我做错了什么?

PS - 我已加入time.hsys/time.h

3 个答案:

答案 0 :(得分:2)

struct timeval成员的类型因系统而异。与许多其他C数据类型一样,安全和便携的事情是在打印时转换值:

printf("Rcvd pkt from %s:%d at <%ld.%06ld>\n",
    inet_ntoa(servAddr.sin_addr),  ntohs(servAddr.sin_port),
    (long) timeVal.tv_sec, (long) timeVal.tv_usec);

对于任何小于或等于long的数据类型,这都可以正常工作。这个习惯用法非常普遍,以至于人们会考虑使这些常见数据类型的长度超过很长时间,但要注意引用文件大小的数据类型(如off_t);在某些情况下,这些可能是long long

为了最大限度地安全,您将转换为long long并使用%lld格式,但这会将另一个可移植性问题转换为另一个,因为并非所有printf实现都支持{{1但是。而且我没有看到那些时间值需要处理的实现。

答案 1 :(得分:1)

有关suseconds_t的说明,请参阅sys/types.h。显然,它是

  

有符号整数类型,能够存储至少在[-1,1,000,000]范围内的值。

这意味着它可能在您的系统上定义为int。尝试从格式字符串中删除长说明符l,然后将其打印为常规小数。

修改

根据rra的回答,这不可移植。它仅适用于以相同方式定义suseconds_t的系统。我们从规范中知道该类型是至少32位的有符号整数类型。最便携的方法是将它转换为你可以逃脱的最大的签名积分内在。

答案 2 :(得分:1)

将数字转换为正确的类型:

printf("Rcvd pkt from %s:%d at <%ld.%06ld>\n", inet_ntoa(servAddr.sin_addr),  ntohs(servAddr.sin_port), (long int)(timeVal.tv_sec), (long int)(timeVal.tv_usec));