我在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;
}
答案 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 -Wall sven.c -o sven
进行编译我没有得到任何警告。甚至使用gcc-4.7 -Wall
。它可能是libc
... 中的<stdio.h>
标题问题