2013-09-28 74 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調用提供了兩個。

但是在你的代碼中,格式化字符串不是一個文字,而是一些其他函數產生的值。編譯器不夠聰明,無法確定該字符串應該是什麼,所以它會向您發出警告,告訴您它不會給您提供您期望的安全網。

只要您確定生成警告的調用實際上是正確的,那麼忽略或抑制此警告是安全的。

相關問題