2013-09-28 37 views
1

我试图学习C并已经遇到了问题。 我认为它微不足道,但我需要知道它。我已经写:警告:格式不是字符串文字,参数类型没有检查

char *seconds_to_string (guint seconds) 
{ 
    long days, hours, minutes; 
    char *time = NULL; 
    const char *minutefmt; 
    const char *hourfmt; 
    const char *secondfmt; 

    days = seconds/(60 * 60 * 24); 
    hours = (seconds/(60 * 60)); 
    minutes = (seconds/60) - ((days * 24 * 60) + (hours * 60)); 
    seconds = seconds % 60; 

    minutefmt = ngettext ("%ld minute", "%ld minutes", minutes); 
    hourfmt = ngettext ("%ld hour", "%ld hours", hours); 
    secondfmt = ngettext ("%ld second", "%ld seconds", seconds); 

    minutefmt = ngettext ("%ld minute", "%ld minutes", minutes); 
    hourfmt = ngettext ("%ld hour", "%ld hours", hours); 
    secondfmt = ngettext ("%ld second", "%ld seconds", seconds); 

    char *fmt; 
    /* Translators: the format is "X hours X minutes X seconds" */ 
    fmt = g_strdup_printf (_("%s %s %s"), hourfmt, minutefmt, secondfmt); 
    time = g_strdup_printf (fmt, hours, minutes, seconds); 
    g_free (fmt); 

    --------------------------------------------------------------------- 

    return time; 
} 

警告符合:

time = g_strdup_printf (fmt, hours, minutes, seconds); 

谁能帮助吗?

UPDATE:

编译

scan-build make CFLAGS='-Wformat-nonliteral' 
+0

你能告诉我们'g_strdup_printf'的原型吗?这听起来像你的参数不适合原型类型。 – dhein

+0

通过以相反的顺序执行操作,您可以避免发出警告:首先将小时,分钟和秒值分别格式化为其自己的字符串,然后将这些字符串与_(“%s%s%s”)一起格式化。 – ptomato

回答

2

这只是一个警告。

g_strdup_printf(),像printf(),使用第一个参数作为格式说明,如果它的字面像"%d Hours:%d Minutes"一个字符串,编译器可以检查下面的参数,看是否匹配类型。 (在这个例子中,如果两个参数的类型是int

但是在你的代码中,格式说明符不是字符串文字,而是手动生成的字符串,所以编译器不能检查类型您。

0

没有你指定你正在使用的编译器很难确切知道,但对我来说,它看起来像你得到的警告是良性的。看起来你的编译器通常可以根据提供的格式字符串对printf进行一些检查:例如,如果你说printf("%d", arg1, arg2)它可能会注意到你的格式字符串需要一个参数,但你的printf调用提供了两个。

但是在你的代码中,格式化字符串不是一个文字,而是一些其他函数产生的值。编译器不够聪明,无法确定该字符串应该是什么,所以它会向您发出警告,告诉您它不会给您提供您期望的安全网。

只要您确定生成警告的调用实际上是正确的,那么忽略或抑制此警告是安全的。

相关问题