如何在包含“%s”的字符串上执行strcmp&引用;在C中?

如何在包含“%s”的字符串上执行strcmp&引用;在C中?,c,linux,unix,C,Linux,Unix,我有一个解析配置文件的C程序。配置文件允许以下格式的一些wildchar 选项=%any 问题是,当我使用strcmp比较值时,我得到一个非法的指令错误 用于说明这一点的示例程序: char str1[10]; sprintf(str1,"%any"); if(strcmp(str1,"%any") == 0) printf("match\n"); return 0; 输出: $ ./a.out Illegal instruction printf也会抛出此错误 与 p

我有一个解析配置文件的C程序。配置文件允许以下格式的一些wildchar
选项=%any

问题是,当我使用strcmp比较值时,我得到一个非法的指令错误

用于说明这一点的示例程序:

char str1[10];
sprintf(str1,"%any");

if(strcmp(str1,"%any") == 0) 
        printf("match\n");

return 0;
输出:

$ ./a.out
Illegal instruction
printf也会抛出此错误

与 printf(“%s\n”,str1)

输出为:

$ ./a.out
0x0.07fff00000001p-1022ny
Illegal instruction
我尝试了转义,即在sprintf中使用“\%any”而不是“%any”;但这没用

在C++中,使用STD::String==比较,使用CUT打印似乎很好。


有人能帮我找出如何使用C来实现这一点吗?

它来自
sprintf

#include <stdio.h>

sprintf(str1, "%%any");
#包括
sprintf(str1,“%任何”);

正如Paul R.所说,您可以使用strcpy,而不必担心这些格式

在这种情况下,您可能应该编写以下内容之一:

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.07fff0000001p-1022ny
,它是一个十六进制浮点值
0x0.07fff0000001p-1022
,后跟
ny
。您得到的非法指令错误可能是因为您破坏了存储在堆栈上的返回地址,因此当您的函数返回时,它会跳转到无效地址

根据经验,如果您使用了一个
printf
函数,并且在格式字符串后没有指定至少一个vararg,则很有可能是您做错了什么。
printf
中的
f
的意思是该函数进行格式化,但您在没有任何要格式化的内容时使用它。所以它只是一个字符串副本,有额外的机会出错

如果您想使用
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
}
如果您不知何故知道
某些字符串
适合您的缓冲区,那么您可以省略错误处理和/或使用
strcpy
。但是当你这么做,把长度弄错的时候,你看起来很愚蠢

您还可以使用
sizeof(str1)
代替
str1\u SIZE
,前提是
str1
是一个数组(如此处所示),而不是指针(如大多数字符串处理代码中所示)

我尝试了转义,即在sprintf中使用“\%any”而不是“%any”;但这没用

不错的尝试,没有雪茄;-)

反斜杠用于转义字符串文字中的特殊字符。由于
%
在字符串文本中没有任何特殊含义,因此转义它没有任何效果。结果字符串为五个字符
%
a
n
y
\0


稍后将该字符串传递给
sprintf
。现在,
%
有了特殊的含义,并且有了一种不同的转义方式:
%

更好的方法是使用strcpy而不是sprintf。@PaulR不是,而是
strncpy()
snprintf()
。我们应该真正避免使用不安全的函数(即那些不带长度参数的函数)。@H2CO3:我同意
snprintf
,但不同意
strncpy
。此函数不是为空终止字符串而设计的。或者,
sprintf(str1、%s、%any”)。当
%any`不是文本时,此变体工作得更好,可以轻松地向字符串添加内容。当然,它也应该是
snprintf
@H2CO3 strncpy不是strcpy的安全版本。在
printf()
的每一个像样的文档中都记录了
%
的转义。为什么不读一本这些文档呢?不应该因为太本地化而关闭。。。询问如何逃逸
%
一点也不本地化。@djechlin不阅读文档会使这个问题过于本地化(对于那些不阅读文档的人)。@H2CO3不,这是一个非常自由的解释,不阅读文档并不构成“非常狭窄的情况”“下一票”作为“下一票”错误的工具提示的糟糕研究工作是恰当的。@djechlin我希望你不会真的认为我还没有阅读常见问题解答。