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