从c中的字符串中删除尾部空白时出现分段错误



我正在尝试删除字符串末尾的空白。我有以下代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
char *trim(char *str) {
char *end;
end = str + strlen(str) - 1;
while(end > str && isspace((unsigned char)*end)) {
end--;
}
*(end++) = ''; //this line causes the segfault
return str;
}
int main(void) {
char *str = "mystring  ";
printf("before trim string is %sn", str);
printf("length before: %dn", strlen(str)); //should be 10
str = trim(str);
printf("after trim string is %sn", str);
printf("length after: %dn", strlen(str)); //should be 8
return 0;
}

当我运行代码时,我会遇到分段错误。我不确定的是,为什么将指针"end"增加1,然后将其指向的值从空白更改为null终止符会导致segfault。我读到,在C中增加指针,使指针不指向数组的元素是未定义的行为。然而,"mystring"末尾的空白不是仍然是char数组str[]的一部分吗?非常感谢您的帮助。

这里的问题是导致崩溃的行试图修改字符串文字,这导致了未定义的行为。

根据https://en.cppreference.com/w/c/language/string_literal,

字符串文字是不可修改的(事实上,可以放在.rodata等只读内存中(。如果程序试图修改由字符串文字形成的静态数组,则行为是未定义的。

您必须确保将char*传递给可修改的数组,例如您用malloc()为自己分配的数组。

其他响应都是正确的,但我很惊讶您的编译器没有发现错误。以下是Visual Studio 2017的良好编译和运行。

注意trim((中也有一个小错误

*(++end) = ''; NOT
*(end++) = '';

现在一切都好。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
char *trim(char *str) {
char *end;
end = str + strlen(str) - 1;
while (end > str && isspace((unsigned char)*end)) {
end--;
}
*(++end) = ''; //this line causes the segfault
return str;
}
int main(void) {
char str0[] = "mystring  "; // minor change here
char *str = str0;           // minor change here
printf("before trim string is %sn", str);
printf("length before: %dn", strlen(str)); //should be 10
str = trim(str);
printf("after trim string is %sn", str);
printf("length after: %dn", strlen(str)); //should be 8
return 0;
}

用指针处理字符串时,编译器将"="后常量字符串第一个字符的存储地址分配给指针,常量字符串存在于只读内存中。您可以尝试这两种代码来观察差异:

int main()
{
char str[] = "abcd";
*str = 'c';
printf("%sn", str);
return 0;
}
int main()
{
char *str = "abcd";
*str = 'c';    // error
printf("%s", str);
return 0;
}

最新更新