我们都知道C语言标准库操作文件写有一个函数叫做fprintf,用来写出字符串到文件里。这个函数如果不特别注意,会给我们带来很大的麻烦。
比如下面的代码段:
const char* outstring = "xxxxx";
FILE* outfileH = fopen("test.txt", "w");
if (!outfileH) {
return false;
}
fprintf(outfileH, $outstring);
fclose(outfileH);
return true;
上面这段代码在大部分情况都能工作正常,但是如果outstring中包含"%",会给带来很大的麻烦。我想你已经知道原因了。
原因在于上面的fprintf函数调用方法不对,fprintf函数的第二个参数是字符串格式化方法的字符串,以%来标记格式化的策略,第三个参数之后的参数提供被格式化的内容列表。在上面的例子中,从第三个参数开始,我们都没有提供任何参数。如果outstring字符串中包含%s字符串,那么函数需要提供一个字符串,但是后面的参数列表中,我们并没有提供,那么函数内部就会按照参数压栈的顺序,往栈上面定位一个想要的字符串。然而这是非常危险的,要知道我们并没有提供任何被格式化的字符串作为参数,将它们压到栈中。程序就会访问非法的内存空间。
解决办法就是调用fwrite函数,而不是fprintf,如果上面并没有格式化输出的需求。