繁体   English   中英

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

[英]Segmentation fault when removing trailing whitespace from string in 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++) = '\0'; //this line causes the segfault
   return str;
}

int main(void) {
   char *str = "mystring  ";
   printf("before trim string is %s\n", str);
   printf("length before: %d\n", strlen(str)); //should be 10
   str = trim(str);
   printf("after trim string is %s\n", str);
   printf("length after: %d\n", strlen(str)); //should be 8
   return 0;
}

运行代码时,我遇到了段错误。 我不确定的是为什么将指针“ end”增加1,然后将其指向的值从空格更改为空终止符会导致段错误。 我已经读过,在C中增加一个指针,使该指针不指向数组的元素是未定义的行为。 但是,“ mystring”末尾的空格是否仍不属于char数组str []的一部分? 任何帮助都非常感谢。

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

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

字符串文字是不可修改的(实际上可能放在.rodata之类的只读存储器中)。 如果程序尝试修改由字符串文字形成的静态数组,则该行为是不确定的。

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

其他响应是正确的-但令您惊讶的是编译器没有收到该错误。 下面的代码可以在Visual Studio 2017中编译并正常运行。

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

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

现在一切都好。

#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) = '\0'; //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 %s\n", str);
    printf("length before: %d\n", strlen(str)); //should be 10

    str = trim(str);
    printf("after trim string is %s\n", str);
    printf("length after: %d\n", strlen(str)); //should be 8
    return 0;
}

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM