2012-05-05 60 views
0

我在最后一行得到一个“int格式,不同类型arg(arg 4)”错误。我应该只投射到int还是有更好的方法来处理这个?Cast off_t到int

struct stat info; 
if (stat(file_path, &info) == -1 || errno == ENOENT) 
    return -1; 

if (stat(file_path, &info) != -1) 
{ 
    char buf[LINELEN]; 
    snprintf(buf,LINELEN,"File Size: %d",info.st_size); 
+3

关于'printf'(这让我真的很难过)的坏处恰恰就是格式字符串的问题。想象你的代码根据某种配置typedefs为'uint32_t'或'uint64_t'的类型。你永远不能只是printf这些变量。但是,绝大多数工作没有问题的解决方案是将参数转换为它们可以承担的最大大小。以你的情况为例:'printf(“%lu”,(unsigned int)info.st_size);'无论大小如何,都能正确打印。唯一的问题是,如果论点比你的演员大。你会失去数据,但仍然避免UB。 – Shahbaz

回答

0

改为尝试格式%ld。这取决于你的平台,但通常off_t被定义为long。也可以是无符号的,在这种情况下使用%lu。

0

对于off_t类型,你应该打印这样的:

snprintf(buf,LINELEN,"File Size: %jd",info.st_size); 

注意的j在格式化。

+0

“j”格式适用于“{u} intmax_t”。所以你也必须投入这种类型以确保。 –

0

st_size的类型是off_t,这实际上是long

所以正确的电话应为:

snprintf(buf,LINELEN,"File Size: %ld",info.st_size); 
+0

“真的很长”?它可以是任何有符号的整数类型。 –

+0

所以,你认为“j”修饰符会出现在所有的实现中吗?假设它是长期的更安全。您可以在不带任何编译器警告的情况下强制转换st_size:'snprintf(buf,LINELEN,“文件大小:%ld”,(long)info.st_size);' – 2012-05-05 10:03:19

+0

“j”修饰符是C标准的一部分。 AFAIR自C99以来就是如此。 –

3

不幸的是没有为off_t定义的格式可以是任何符号的整数类型,根据不同的平台,也对一些宏(调节,如果你可以访问例如大于4 GiB的文件)。你不能依赖这个。最好使用“j”作为printf格式的长度修饰符,并将您的值转换为intmax_t

0

为了安全,正确和可移植:在传递可变参数时总是包含显式转换,例如,如果您要传递的内容在编译时可能不具有相同的类型,则传递给printf。例如,计算出你认为off_t可以得到多大(long应该至少和off_t一样大),然后确保你的printf格式能够接受你现在可以安全地知道你会传入的那一长串。对于可能变化的类型,没有转换的printf会要求麻烦。