Функция конкатенации строк в C ничего не делает, так каков правильный путь? - PullRequest
0 голосов
/ 09 февраля 2012

Я учу язык C ...

Я хочу написать функцию, которая объединяет две строки. Я написал функцию, но она не работает; это не дает никакой ошибки при компиляции, но во время работы ничего не делает.

Вот мой код:

char* str_sum(char* s1, char* s2){
    int j = strlen(s1);
    int i=0;
    while(s2[i]){
            s1[j]=s2[i];
            j++;
            i++;
    }
    return s1;
}
int main(){
    char* s1, s2;
    s1 = "Joe";
    s2 = "Black";
    printf("%s\n",sum_str(s1,s2));
    return 0;
}

Ответы [ 8 ]

2 голосов
/ 09 февраля 2012

Ваша функция может выглядеть следующим образом:

char* sum_str(char* s1, char* s2)
{
    int lenS1 = strlen(s1);
    int lenS2 = strlen(s2);
    char* newString = malloc((lenS1 + lenS2 + 1) * sizeof(char));
    int i = 0;
    while(i < lenS1)
    {
        newString[i] = s1[i];
        i++;
    }
    while(i < lenS2 + lenS1)
    {
        newString[i] = s2[i - lenS1];
        i++;
    }
    newString[i] = '\0';
    return newString;
}

Обратите внимание, что эта функция выделяет новую строку, что означает, что вы должны free эти данные, когда вы закончите с этой строкой.Также обратите внимание, что завершающий символ ('\0') хранится в конце этого массива символов, так что printf может правильно «напечатать» его.

Вот главное:

int main()
{
  char *s1, *s2, *s3;
  s1 = "Joe";
  s2 = " Black";
  s3 = sum_str(s1,s2);
  printf("%s\n", s3);
  free(s3);
  return 0;
}

Вывод: Joe Black

Обратите внимание, что я объявил переменные s1, s2 и s3 следующим образом: char *s1, *s2, *s3;.Если я напишу это так: char *s1, s2, s3;, тогда переменные s2 и s3 больше не являются массивами символов, а только символами.

Также обратите внимание, что эта программа:

  char *s1 = "Joe";
  s1[0] = 'X';
  printf("%s\n", s1);

произойдет сбой, поскольку он пытается изменить константу строкового литерала "Joe".s1 является указателем на первый символ этого литерала в этом случае.

Но эта программа будет работать нормально, и ее вывод будет Xoe:

  char s1[] = "Joe";
  s1[0] = 'X';
  printf("%s\n", s1);

s1 являетсяМассив инициализируется строкой "Joe", поэтому его можно изменить.

1 голос
/ 09 февраля 2012

Примерно так:

char* str_sum(char* s1, char* s2){
   int len = strlen(s1) + strlen(s2);
   char* buff = malloc(len * sizeof(char) + 1);

   strcpy(buff, s1); //we don't need the zero termination char here.
   strcpy(buff + strlen(s1), s2);
   buff[len] = '\0';
   return buff;
}
0 голосов
/ 24 февраля 2014

Вот способ сделать это без каких-либо предопределенных функций.Результат объединения помещается в третий параметр функции, который является строкой результата:

  void str_cat_101(char const input1[], char const input2[], char result[])
  {
     int i, z;
     for(i = 0; input1[i] != 0; i++)
     {
        result[i] = input1[i];
     }
     for(z=0; input2[z] != 0; z++)
     {
        result[i+z] = input2[z];
     }
     result[i+z] = 0;
  }
0 голосов
/ 09 февраля 2012

то, что вы делаете, вызовет ошибку сегментации.Строковые литералы, вероятно, находятся в разделе памяти, доступном только для чтения.Это ошибка времени выполнения, если вы пытаетесь записать в такое место.Вместо этого используйте malloc, как говорят другие ответы.Это ошибка многих начинающих, в том числе и меня.

0 голосов
/ 09 февраля 2012

Вы можете сделать это либо с помощью strcat () или без (что отчасти бессмысленно, но я включаю его для полноты картины. См. пример ниже.

char* str_sum_wstrcat(char* s1, char* s2)
{
    int len1 = strlen(s1);
    int len2 = strlen(s2);
    int i=0;
    char* sum = malloc(len1+len2+1);
    strcpy(sum,s1);
    strcat(sum,s2);


    return sum;
}

char* str_sum(char* s1, char* s2)
{
    int len1 = strlen(s1);
    int len2 = strlen(s2);
    int i=0;
    char* sum = malloc(len1+len2+1);
    strcpy(sum,s1);
    while(i<len2)
    {
        sum[len1+i] = s2[i];
        i++;
    }
    sum[len1+i]='\0';


    return sum;
}

int main()
{
  char* s1 = malloc(100);
  char* s2 = malloc(100);
  s1 = "Joe";
  s2 = "Black";
  printf("%s\n",str_sum(s1,s2));
  //or
  printf("%s\n",str_sum_wstrcat(s1,s2)); 
  return 0;
}
0 голосов
/ 09 февраля 2012

Ваша str_sum функция должна создать массив, достаточно большой для хранения содержимого объединенных строк.

char *str_sum( const char *s1, const char *s2 )
{
  char *ret = malloc( strlen(s1) + strlen(s2) + 1 ); // 1 for terminating NULL char

  if( ret == NULL ) {
    return NULL;
  }
  strcpy( ret, s1 );
  strcpy( &ret[strlen(s1)], s2 );
  return ret;
}

Кроме того, вызывающей стороне потребуется free() возвращенный указательэто не NULL).

0 голосов
/ 09 февраля 2012

Ваша функция не выделяет память для записи вашей новой строки. Может быть, вы могли бы использовать strcat или переписать его так:

char* str_sum(char* s1, char* s2) {
  int l1 = strlen(s1), l2 = strlen(s2), i;
  char sum = (char *)malloc(l1+l2+1);

  for(i=0; i<l1; i++) sum[i] = s1[i];
  for(i=0; i<l2; i++) sum[i+l1] = s2[i];

  sum[l1+l2] = '\0'; // NULL terminated    
  return sum;
}
0 голосов
/ 09 февраля 2012

Существует 2 основных проблемы с кодом:

  1. строка s1 может указывать на постоянную память и не может быть изменена.Запуск вашего примера на моей машине вызывает ошибку сегментации.
  2. строка s1 недостаточно велика для хранения дополнительного содержимого s2.Он должен быть объявлен как: char s1 [30] = "Joe";
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...