Вернуть указатель на массив символов в C - PullRequest
6 голосов
/ 13 апреля 2010

Я видел много вопросов по этому поводу в StackOverflow, но чтение ответов не прояснило это для меня, возможно, потому что я новичок в программировании на Си. Вот код:

#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 о возвращении массивов и попробовал «статический» метод, который предлагается там, но все еще не смог заставить программу работать. Кто-нибудь может указать точно, что с ним не так и на что мне следует обратить внимание в будущем?

Ответы [ 3 ]

6 голосов
/ 13 апреля 2010

1-й аргумент, передаваемый в функцию squeeze, является read-only строковым литералом "hello", который вы пытаетесь изменить.

Вместо этого передайте ему модифицируемый массив символов:

char str[] = "hello";
printf("%s", squeeze(str, 'o'));
3 голосов
/ 13 апреля 2010

Попытка изменить неизменяемые данные.

"привет" - это константа, которая где-то хранится в памяти. То, что вы пытаетесь сделать, это изменить его, и это, как правило, не допускается. Я не понимаю, что вы подразумеваете под "статичным", но то, что вы хотите, было бы что-то вроде ...

int main()
{
  char hello_str[16];
  strcpy(hello_str, "hello");
  printf("%s", squeeze(hello_str, 'o'));
}
3 голосов
/ 13 апреля 2010

Проблема в том, что константа символьный массив "hello" может неправильно изменяться функцией, которой он был передан. Итак, просто убедитесь, что вы передаете неконстантный массив (например, создавая локальный массив для передачи, если результат не нужен вне вызывающей стороны squeeze):

int main()
{
  char xxx[] = "hello";
  printf("%s", squeeze(xxx, 'o'));

  return 0;
}

Можно ожидать, что такую ​​константу можно передать только в аргумент const (чтобы сам компилятор мог сказать вам, что вы делаете неправильно), но, увы, это не то, что предписывает стандарт C предположительно по причинам обратной совместимости с историческим кодом).

...