我试图使用strstr()在字符串中找到子字符串。使用char[]只能工作,char*不能工作,导致分割错误。
所以这个是有效的:
int main() {
char str[] = "apple apple peach";
char *p;
p = strstr(str, "peach");
if (p!= NULL) {
strncpy(p, "apple", 5);
}
return 0;
}
但是这个不工作:
int main() {
char *str = "apple apple peach";
char *p;
p = strstr(str, "peach");
if (p!= NULL) {
strncpy(p, "apple", 5);
}
return 0;
}
这个都不是
int main() {
char *str = "apple apple peach";
char *peach = "peach";
char *p;
p = strstr(str, peach);
if (p!= NULL) {
strncpy(p, "apple", 5);
}
return 0;
}
这个也没有
int main() {
char *str = "apple apple peach";
char peach[] = "peach";
char *p;
p = strstr(str, peach);
if (p!= NULL) {
strncpy(p, "apple", 5);
}
return 0;
}
这是已知的bug或特性吗?
你的问题是不是与strstr
,它与strncpy
。在指针的情况下,您使用strncpy
试图写入字符串文字,这是常数。
string-literal修改不安全! char[]
的成功仅仅是因为strncpy(p, "apple", 5);
修改了string-literal的复制版本,而不是string-literal本身。标准中的相关段落如下:
6.4.5,第6段简而言之,string-literal是将(概念上)替换为数组,修改它是不安全的。注意string-literal不一定是const-qualified,尽管msvc++似乎强制要求string-literal是…然后使用多字节字符序列初始化一个静态存储持续时间和长度刚好足以包含序列的数组…
6.4.5,第七段
…如果程序试图修改这样的数组,则该行为是未定义的。
const char *
或其他const-qualified。
它与strstr
无关:它按预期工作。在strcpy
中,当您试图修改分配给字符串文字的内存时,会发生崩溃。这是未定义的行为。
解决这个问题的关键是将数据放入允许写入的内存中。第一个程序通过将str
声明为数组来实现:
char str[] = "apple apple peach";
这不是UB,所以程序运行到完成。另一种选择是在动态内存中分配str
,如下所示:
char *str = malloc(20);
strcpy(str, "apple apple peach");
char *p;
p = strstr(str, "peach");
if (p!= NULL) {
strncpy(p, "apple", 5);
}
free(str);