snprintf - 格式不是字符串文字,没有格式参数警告

时间:2013-04-15 09:04:04

标签: c linux gcc posix printf

我在Linux上编译时会收到format not a string literal and no format arguments警告。 snprintf为第三个参数显示const char*。定义const char *INTERFACE = "wlan0"然后将其传递给函数有什么问题?

#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;
}

3 个答案:

答案 0 :(得分:4)

警告的后半部分(“没有格式参数”)意味着该字符串不包含任何% s,因此使用snprintf()就没有意义了这样做。

值得警告,因为它可能存在安全风险,如果字符串参数在运行时是可变的,那么%可能会“悄悄进入”,这将导致问题。因此,如果格式化字符串被硬编码为“做你想做的事”,那就更好了。

如前所述,在这种情况下使用snprintf()毫无意义。

答案 1 :(得分: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'字符。

答案 2 :(得分: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。它可能是libc ...

中的<stdio.h>标题问题