如何更改字符串中的字符?

时间:2018-02-04 19:12:48

标签: c

我希望有一个函数接收字符串作为参数并更改字符串的符号

char *strChanger(char *str)

我试图像这样实现它:

char *strChanger(char *str) {
    if(str[0] != '\0') {
        str[0] = 'a';
    }
    return str;
}

在程序中它应该看起来像char *newstr = strChanger("hi");

但是当我尝试更改字符串中的字符时,程序会崩溃。

我做了一些实验并发现:

// Works fine
char str[] = "hi";
str[0] = 'a';

// Crashes
char *str = "hi";
str[0] = 'a';

我不明白其中的区别。为什么第二个代码块不起作用?

1 个答案:

答案 0 :(得分:3)

因为修改字符串文字是undefined behavior - 在您的情况下会导致程序崩溃。

在第二个示例中,您传递字符串文字direclty并尝试对其进行更改。用char *newstr = strChanger("hi")来表达。

实际上char *str = "hi";基本上使str指向字符串文字。更具体地说,string literal is an array被转换为指向第一个元素的指针,然后被分配给str。然后你试图修改它 - 这是未定义的行为。

在第一种情况下,它的副本是可修改的,你可以对它进行更改,然后传递它并且它可以工作。您正在声明一个char数组并使用字符串文字的内容对其进行初始化。

如果您已定义POSIX "strdup",那么您可以执行此操作

char *newstr = strChanger(strdup("hi"));

但是再次在strChanger内部,您需要检查传递的值 - strdup可能会返回NULL,以防它无法分配内存并为您提供复制的字符串。在使用这样的某个时刻后,你将不得不释放记忆 - free(newstr)

来自字符串文字

下的标准6.4.5p7
  

如果这些数组的元素具有适当的值,则未指定这些数组是否相同。 如果程序试图修改此类数组,则行为未定义。

初始化下的6.7.9p14

  

字符类型数组可以由字符串文字或UTF-8字符串文字初始化,可选择用大括号括起来。 字符串文字的连续字节(如果有空间或数组大小未知,则包括终止空字符)初始化数组的元素。