0

我正在尝试使用 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;
}

这是一个已知的错误或功能吗?

4

3 回答 3

5

你的问题在于strstr,而在于strncpy。在指针的情况下,您正在strncpy尝试写入字符串字面量,它是常量。

于 2016-11-06T10:07:13.077 回答
3

字符串文字不安全修改!withchar[]成功只是因为strncpy(p, "apple", 5);修改了 string-literal 的复制版本不是string-literal本身。标准中的相关段落如下:

6.4.5,第 6 段

...然后使用多字节字符序列来初始化一个静态存储持续时间和长度的数组,刚好足以包含该序列...

6.4.5,第 7 段

...如果程序尝试修改这样的数组,则行为未定义。

简而言之,字符串文字(在概念上)被替换为数组,修改它是不安全的。请注意,字符串文字不一定是 const 限定的,尽管 MSVC++ 似乎要求string-literalconst char *或某些是 const 限定的。

于 2016-11-06T10:10:06.610 回答
1

它与 无关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);
于 2016-11-06T10:07:33.043 回答