【问题标题】:C: How can I edit a C-string in a function without using mallocC:如何在不使用 malloc 的情况下在函数中编辑 C 字符串
【发布时间】:2016-09-23 02:31:51
【问题描述】:

我在main 中有一个string,我想将该字符串的地址传递给将编辑该字符串内容的函数。我不想使用 malloc。

我的代码目前如下所示:

int main(){
        char* str = "Hello";
        char* para1[] = {"Tea", "Coffee"};

        printf("str: %s\n para1: %s\n", str, para1[0]);

        my_func(str, &para1);

        printf("str: %s\n para1: %s\n", str, para1[0]);

        return 1;
}

int my_func(char* str, char** para1){
        printf("str: %s\n", str);
        str[0] = 'W';
        para1[0] = "Popcorn";

        return 1;
}

我不明白如何将字符串的第一个字母从H 更改为W

你能解释一下我做错了什么吗?

【问题讨论】:

  • 1) char* str = "Hello"; --> char str[] = "Hello"; 2) my_func(str, &para1); --> my_func(str, para1); 另外你必须有一个原型才能使用这个功能。
  • @BLUEPIXY 在 C89 中,这个函数可以在没有原型的情况下调用,不幸的是,即使现代编译器仍然默认为 C89 模式,可能没有警告
  • 你可以定义一个像typedef struct { char data[80]; } punchcard_t这样的punchard类型并将字符串作为punchcard_t传递给函数,并让它返回punchcard_t(字符串长度被保留,不像通过引用传递)。否则,您需要 malloc 或 malloc 的本地静态内存池实现,因为您无法返回指向本地数据的指针,因为它的生命周期已到期。这是有效的,因为结构充当字节数组的包装器,因此将其结构保留为输入类型和返回类型(而您不能“返回”char[80])。
  • 永远不要使用制表符进行缩进。每个文字处理器/编辑器都为个人喜好设置了制表位/制表位宽度。建议为每个缩进级别使用 4 个空格,因为它足够宽,即使使用可变宽度字体也可以看到,并且允许整个页面有多个缩进级别

标签: c string function pointers c-strings


【解决方案1】:

字符串文字是只读的。当你定义:

char* string_literal = "Hello";

您将获得一个指向位于只读内存中的文本“Hello”的指针。

如果将其声明为 char 数组:

char string[] = "Hello";

然后你可以用数组索引表示法修改string的内容:

string[0] = "W";

现在,您可以将指向字符串文字的指针替换为指向另一个字符串文字的指针。例如,

string_literal = "New string literal";

因为在这里您实际上正在做的是重新分配名为“string_literal”的指针以指向内存中的另一个地址。指针本身是可写的,但它指向的内存是只读的。这就是您对 para1 的分配成功的原因。

【讨论】:

    【解决方案2】:

    字符串字面量不可修改的,因为它们通常存储在您的 exe 的不可变数据部分中。


    这与你的功能无关,以这个玩具为例:

    include <stdio.h>
    
    int main(void)
    {
        char* str = "Hello";
        str[0] = 'g';
        printf("%s\n", str);
        return 0;
    }
    

    这应该会导致运行时错误,我得到了:

    C02QT2UBFVH6-lm:~ gsamaras$ gcc -Wall main.c 
    C02QT2UBFVH6-lm:~ gsamaras$ ./a.out 
    Bus error: 10
    

    关于这个主题的信息很多,所以我不会再展开了。

    【讨论】:

    • 我不知道谁对我投了赞成票,但他/她的投票让我达到了 20k rep mliesstone !!! :D
    • 恭喜!! (*^_^)_∠※☆PAN!
    • @BLUEPIXY ありがとう,谁知道也许有一天我可以效仿你!
    【解决方案3】:

    字符串字面量存储在read-only part of the memory,所以你不能修改它们。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-07-18
      • 1970-01-01
      • 1970-01-01
      • 2012-09-06
      • 2017-09-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多