在C语言中返回一个指向字符数组的指针

6

我在StackOverflow上看到了很多关于这方面的问题,但是阅读答案并没有为我澄清,可能是因为我对C编程完全是新手。这是代码:

#include <stdio.h>

char* squeeze(char s[], char c);

main()
{
  printf("%s", squeeze("hello", 'o'));
}

char* squeeze(char s[], char c)
{
  int i, j;

  for(i = j = 0; s[i] != '\0'; i++)
    if(s[i] != c)
      s[j++] = s[i];
    s[j] = '\0';

  return s;
}

当我编译它并运行时,会出现分段错误。我已经阅读了关于返回数组的这篇faq,并尝试了其中建议的“静态”技术,但仍无法使程序正常工作。请问有谁能指出问题所在并告诉我将来应该注意什么?


@snitko:main() 函数的返回类型在哪里? - Prasoon Saurav
3个回答

6
squeeze函数的第一个参数是一个只读字符串字面量"hello",你正在尝试修改它。相反,传递一个可修改的字符数组:
char str[] = "hello";
printf("%s", squeeze(str, 'o'));

1
可以运用最少惊讶原则来建议复制字符串。如果我将char传递到返回char的函数中,我可能不会预料到它会直接修改数组。(API设计者在使用const时经常粗心大意。) - Nicholas Knight

3
问题在于传递给函数的常量字符数组 "hello" 可能无法被正确修改。因此,请确保传递非常量数组(例如通过创建本地数组进行传递,只要结果不需要在 squeeze 的调用方之外使用即可):
int main()
{
  char xxx[] = "hello";
  printf("%s", squeeze(xxx, 'o'));

  return 0;
}

你可能会认为这样的常量只能传递给一个const参数(这样编译器本身就可以告诉你你在做什么错误),但不幸的是,C标准并没有规定这样做(可能是为了与历史代码的向后兼容性)。


1
这个字符串并不是临时存储的,它被存储在“静态”内存中。 - dash-tom-bang

3

这是试图修改不可修改的数据。

"hello" 是一个常量字符串,存储在内存中的某个位置。因此,你试图去改变它,一般来说是不允许的。我不明白你所说的 "static",但你想要的可能是这样的...

int main()
{
  char hello_str[16];
  strcpy(hello_str, "hello");
  printf("%s", squeeze(hello_str, 'o'));
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接