我已阅读帖子 sprintf format specifier replace by nothing ,以及其他相关信息,但未详细说明。
直到今天,我从未见过sprintf
只使用了2个参数
我的系统用于sprintf()
的原型是:
int sprintf (char Target_String[], const char Format_String[], ...);
在处理一些遗留代码时,我遇到了这个问题:(简化说明)
char toStr[30];
char fromStr[]={"this is the in string"};
sprintf(toStr, fromStr);
我对原型的解释是第二个参数应该由const char[]
组成,并接受标准的ansi C格式说明符such as these。
但上面的例子似乎与字符串fromStr
作为第二个参数一样正常
是纯粹通过未定义的行为这是否有效?或者这种用法完全合法?
我使用C99编译器在Windows 7上工作。
答案 0 :(得分:2)
完全合法。可变参数是可选的。
在这种情况下,printf用作strcpy,但为%说明符解析fmt字符串。
我写sprintf(toStr,"%s",fromStr);
所以它不必解析那个长字符串。
答案 1 :(得分:1)
您正在观察的行为是正确的,格式字符串不需要具有任何转换说明符。在这种情况下,由...
表示的可变长度参数列表的长度为零。这是完全合法的,虽然它的效率肯定低于等效的
strcpy(toStr, fromStr);
答案 2 :(得分:1)
这是完全合法的代码,但
strcpy()
。答案 3 :(得分:1)
sprintf
的概要是:
int sprintf(char *str, const char *format, ...);
这意味着2个参数是合法的选择。
答案 4 :(得分:1)
它起作用,因为你没有其他参数(即没有控制格式%
)来打印。
与没有第二个参数的printf
没有区别:
int printf ( const char * format, ... );
如果您没有任何第二个参数,它也可以使用:
printf(fromStr);
答案 5 :(得分:1)
第二个参数应该由
组成const char[]
函数参数的const
说明符保证函数不会更改该参数的值(假设它可以更改它,这是数组的情况,因为它们通过地址传递给函数)。它不需要在实际调用中使用const值。
您发布的代码不使用const字符串作为sprintf()
的第二个参数,但是从非const到const的转换是隐式的;没有必要担心。
接受标准的ansi C格式说明符
“接受”并不意味着“要求”。您指定的格式字符串不包含任何格式说明符。因此,仅使用2个参数调用该函数(没有要格式化的值)。无论如何,sprinf()
将忽略第三个参数,许多现代编译器会发出警告。
更新:我不想开始讨论哪些编译器是现代的,哪些不是。
碰巧我在OSX 10.11上使用默认编译器,这就是它输出的内容:
axiac: ~/test$ cc -v
Apple LLVM version 7.0.2 (clang-700.1.81)
Target: x86_64-apple-darwin15.3.0
Thread model: posix
axiac: ~/test$ cc -o 1 1.c
1.c:8:25: warning: data argument not used by format string [-Wformat-extra-args]
sprintf(x, "abc\n", n);
~~~~~~~ ^