Возвратите указатель на массив символов в C

Я видел много вопросов на этом на StackOverflow, но чтение ответов не разрешало это для меня, вероятно, потому что я - общий новичок в программировании C. Вот код:

#include 

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;
}

Это компилирует, и я получаю отказ сегментации, когда я выполняю его. Я считал эти часто задаваемые вопросы об о возврате массивов и попробовал 'статическую' технику, которая предлагается там, но все еще не могла получить работу программы. Кто-либо мог указать точно что случилось с ним и что я должен обращать внимание в будущем?

6
задан snitko 13 April 2010 в 02:06
поделиться

3 ответа

Первым аргументом, переданным функции сжатия, является строковый литерал только для чтения «hello» , который вы пытаетесь изменить.

Вместо этого передайте ему изменяемый массив символов:

char str[] = "hello";
printf("%s", squeeze(str, 'o'));
6
ответ дан 9 December 2019 в 20:41
поделиться

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

«hello» - это постоянная строка, хранящаяся где-то в памяти. В таком случае вы пытаетесь изменить это, а это обычно недопустимо. Я не понимаю, что вы имеете в виду под «статикой», но вам нужно что-то вроде ...

int main()
{
  char hello_str[16];
  strcpy(hello_str, "hello");
  printf("%s", squeeze(hello_str, 'o'));
}
3
ответ дан 9 December 2019 в 20:41
поделиться

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

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

  return 0;
}

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

3
ответ дан 9 December 2019 в 20:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: