我在过去的代码中多次使用过这种类型的约定:
strcpy ( cTmpA, "hello" );
sprintf ( cTmpA, "%s world", cTmpA );
Run Code Online (Sandbox Code Playgroud)
最近我将我的遗留C编译器切换到Visual Studio 2005,发现我得到了一个由上面的代码产生的乱码.然后我想到,sprintf()的行为可能没有严格定义,其中一个输入与输出字符串匹配.
以上代码是否有效K&R C?如果没有,我如何找到我的代码中发生此类调用sprintf()的所有位置?
大多数实现sprintf()
不复制格式字符串,而是在您传递的字符串中使用指针.如果格式和输出指向同一个内存,那将导致奇怪的结果.
你真的应该用snprintf()
它来保护你免受缓冲区溢出.
要查找所有呼叫,请放入#define sprintf +++
公共标头查找并重新编译所有源.这应该给你一个错误列表以及文件名和行号:)或者使用你的IDE的递归搜索.
如果要将此列表修剪为对两个参数使用相同指针的列表,请使用此宏:
#define sprintf(output,format,...) check_sprintf(__FILE__,__LINE__,output,format,....)
Run Code Online (Sandbox Code Playgroud)
请注意,并非所有编译器都支持使用varargs的宏.然后定义一个新函数check_sprintf
:
int check_sprintf (char*filename,int line,char*output,char*format,...) {
va_list args;
int len;
if(output==format) {
fprintf(stderr,
"Output and format are the same at %s:%d", filename, line);
abort();
}
va_start (args, format);
len = vsprintf (output, format, args);
va_end (args);
return len;
}
Run Code Online (Sandbox Code Playgroud)
[编辑]我刚看到你在谈论输出和第一个参数.您可以重用上面的代码并调用va_arg()
以获取第一个参数并在比较中使用它.
归档时间: |
|
查看次数: |
8841 次 |
最近记录: |