C snprintf-格式不是字符串文字且无格式参数警告

C snprintf-格式不是字符串文字且无格式参数警告,c,linux,gcc,posix,printf,C,Linux,Gcc,Posix,Printf,当我在Linux上编译它时,我得到了格式而不是字符串文本和无格式参数的警告。显示第三个参数的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 = "

当我在Linux上编译它时,我得到了
格式而不是字符串文本和无格式参数的警告。显示第三个参数的
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;
}
#包括
#包括
#包括
int main(int argc,char*argv[]){
const char*INTERFACE=“wlan0”;
结构ifreq-ifr;
memset(&ifr,0,sizeof(ifr));
snprintf(ifr.ifr\u名称,sizeof(ifr.ifr\u名称),接口);
返回0;
}
这没什么错(这就是为什么它是一个警告而不是一个错误),只是
printf
函数族最常见的用法是使用文本格式字符串

比如:

在您的情况下,您可能应该使用,例如:

定义最小值(a,b)((a)<(b)?(a):(b)) memcpy(ifr.ifr_名称,接口,MIN(strlen(接口)+1,sizeof(ifr.ifr_名称));

还有一种方法可能有效,但有时它不会添加终止的
'\0'
字符。

它只是一个警告,因此您可以忽略它

但在您的情况下,不值得使用
snprintf
,只需编写代码即可

  strncpy (ifd.ifr_name, sizeof(ifr.ifre_name), INTERFACE);
这可能会运行得更快,更重要的是不要发出警告。如果要确保名称以null结尾,请使用
ifd.ifr\u name[sizeof(ifr.ifre\u name)-1]=(char)0;


顺便说一句,对于最近的GCC 4.8,以及使用
GCC-4.8-Wall sven.c-o sven编译,我没有收到任何警告。即使使用
GCC-4.7-Wall
。这可能是
中的
libc
标题问题。

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

值得注意的是,这可能会带来安全风险,如果字符串参数在运行时可更改,则
%
可能会“潜入”,这将导致问题。因此,最好将格式化字符串硬编码为“随心所欲”


如前所述,在这种情况下使用
snprintf()
没有任何意义。

我没有收到任何警告:似乎没有问题,它是
const char*format
看起来像“%s”,您有什么版本的GCC?(只需运行
GCC-v
即可了解)。我想你可能有一个比4.7旧的GCC;那么升级你的编译器是值得的…(例如升级到GCC 4.8)。它是
GCC版本4.7.2(Ubuntu/Linaro 4.7.2-2ubuntu1)
,感谢你提示+1提到安全风险。惯用用法(如果你真的必须使用snprintf)应该是
snprintf(str,sizeof(str),“%s”,foo);
#define MIN(a, b) ((a) < (b) ? (a) : (b))

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