2013-04-15 146 views
1

當我在Linux上編譯它時,得到format not a string literal and no format arguments警告。 snprintf顯示了第三個參數的const char*。定義const char *INTERFACE = "wlan0"然後將它傳遞給函數有什麼不對?snprintf - 格式不是字符串文字,也沒有格式參數警告

#include <stdio.h> 
#include <net/if.h> 
#include <string.h> 

int main(int argc,char *argv[]){ 
    const char *INTERFACE  = "wlan0"; 
    struct ifreq ifr; 

    memset(&ifr, 0, sizeof(ifr)); 
    snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), INTERFACE); 

    return 0; 
} 
+1

我沒有得到任何警告:http://ideone.com/BdSQF2似乎沒問題 – duDE

+0

它是'const char * format',看起來像「%s」 – MYMNeo

+0

你有什麼版本的GCC? (只需運行'gcc -v'即可找到)。 –

回答

3

這是無可厚非(這就是爲什麼它是一個警告,而不是一個錯誤),它只是使printf家庭功能的最常見的用途使用文字格式字符串。

像:

snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", INTERFACE); 

在你的情況,你或許應該使用例如memcpy代替:

#define MIN(a, b) ((a) < (b) ? (a) : (b)) 

memcpy(ifr.ifr_name, INTERFACE, MIN(strlen(INTERFACE) + 1, sizeof(ifr.ifr_name)); 

還有strncpy這可能會工作,但什麼時候會不添加終止'\0'字符的情況下。

1

這只是一個警告,所以你可以忽略它。

但它不值得你的情況使用snprintf ,只是代碼

strncpy (ifd.ifr_name, sizeof(ifr.ifre_name), INTERFACE); 

這可能運行得更快,而且更重要的是不給警告。如果你想確定這個名稱是空的,那麼強制它與ifd.ifr_name[sizeof(ifr.ifre_name)-1] = (char)0;

順便說一句,最近GCC 4.8,編譯gcc-4.8 -Wall sven.c -o sven我沒有得到任何警告。甚至與gcc-4.7 -Wall。這可能是一個<stdio.h>libc問題... ...

4

警告(「無格式參數」)的後半部分是指字符串不包含任何%以及由此導致的沒有一點使用snprintf()像你這樣做。

這是值得警告的,因爲它可能是一個安全風險,如果字符串參數在運行時變化可能是一個%可以「偷偷」,這將導致問題。因此,如果格式化字符串被硬編碼爲「做你想做的」,那將會更好。

如前所述,在這種情況下根本沒有必要使用snprintf()

+1

+1提及安全風險。習慣用法(如果你真的必須使用snprintf)應該是'snprintf(str,sizeof(str),「%s」,foo);' – Roddy

相關問題