在这种情况下,你应该写下列之一:
char str1[10] = "%any";
char str1[] = "%any"; // str1 has size 5
const char *str1 = "%any"; // str1 points to a string literal
在格式化字符串%a
是一个十六进制浮点格式。除了没有提供double
参数(导致未定义的行为)之外,这可能会写入超过10个字节,因此会超出缓冲区str1
(导致未定义的行为)。
这就是为什么你看到0x0.07fff00000001p-1022ny
,这是一个十六进制浮点值0x0.07fff00000001p-1022
其次是ny
。也许你得到的非法指令错误是因为你砸碎了堆栈中存储的返回地址,所以当你的函数返回时,它跳转到一个无效的地址。
作为一个经验法则,如果您使用printf
函数之一,并且在格式字符串之后没有指定至少一个可变参数,那么您很可能会做错某些事情。 f
在printf
中的含义是该函数的格式为,但是当您没有任何要格式化的内容时您正在使用它。所以这只是一个字符串副本,有一个额外的机会让它错误。
如果你想使用printf
系列函数的一个写一个字符串,那么你就可以避免意外指定的格式,你不是那个意思是这样的:
sprintf(str1, "%s", SOME_STRING);
,或者利用长 - 检查:
#define STR1_SIZE 10
char str1[STR1_SIZE];
if (snprintf(str1, STR1_SIZE, "%s", SOME_STRING) >= STR1_SIZE) {
// error-handling here
}
假如你不小心知道SOME_STRING
适合你的缓冲区,那么你可以省略错误处理和/或使用strcpy
代替。但是当你这样做的时候你看起来很愚蠢,而且长度错了。
您还可以使用sizeof(str1)
代替STR1_SIZE
提供str1
是一个数组(因为它是在这里),而不是一个指针(因为它是在大多数字符串处理代码)。
我试过转义,即在sprintf中使用“\%any”而不是“%any”;但这并没有帮助。
不错的尝试,没有雪茄;-)
反斜线在一个字符串逃避特殊字符。由于%
并不意味着字符串文字中的任何特殊内容,因此转义它不起作用。由此产生的字符串是五个字符%
,a
,n
,y
,\0
。
稍后,您将该字符串传递给sprintf
。 现在%
有特殊含义,并有不同的转义方式:%%
。
在'printf()'的每一个不错的文档中都记录了'%'的转义。为什么不只阅读其中一份文件? – 2012-11-08 14:43:56
不应该关闭太本地化......问如何转义'%'根本不是本地化的。 – djechlin
@djechlin没有阅读文档使其过于本地化(对于那些不阅读文档的人)。 – 2012-11-08 18:20:35