реализация strcat без изменения входов - PullRequest
0 голосов
/ 22 сентября 2018

Я хочу создать реализацию функции C strcat для объединения двух строк без изменения любой входной строки.Это то, что у меня пока есть

char *my_strcat(char* s1, char* s2)
{
  char* p = malloc(strlen(s1) + strlen(s2) + 1);
  while (*s1 != '\0')
    *p++ = *s1++;
  while (*s2 != '\0')
    *p++ = *s2++;
  *p++ = '\0';
  return p;
}

Я хочу заполнить p всеми символами в s1 и s2, но этот код просто ничего не возвращает.Могли бы использовать некоторую помощь.

Ответы [ 4 ]

0 голосов
/ 22 сентября 2018

Еще один ответ.На этот раз нет без явного временного указателя символа для сохранения оригинального.И const правильные типы + malloc проверка.

Намного более дружественный оптимизатор компилятора:)

#include<stdio.h>
#include<stdlib.h>
#include <string.h>


static inline char *strcpys(char *dest, const char *src)
{
    while(*dest++ = *src++);
    return dest;
}

char *mystrcat(const char *str1, const char *str2)
{
    char *result = malloc(strlen(str1) + strlen(str2) + 1);

    if(result)
    {
        strcpys(strcpys(result, str1) - 1, str2);
    }
    return result;
}

int main()
{
    char *str1 = "12345";
    char *str2 = "ABCDE";
    char *dest;

    printf("%s + %s = %s\n", str1, str2, (dest = mystrcat(str1, str2)) ? dest : "malloc error");

    free(dest);
    return 0;
}
0 голосов
/ 22 сентября 2018

Я хочу заполнить p всеми символами в s1 и s2, но этот код просто ничего не возвращает.Можно использовать некоторую помощь.

Вы начинаете с указателя malloc, а затем увеличиваете p по мере продвижения.

В конце процедуры, что бы вы сделалиожидайте, что это p будет указывать на?

При таком подходе вам нужно будет запомнить указатель, который у вас был malloc'd, и вернуть его.

Вы можете обнаружить, что если вы дадите свои переменныеболее значимые имена - по крайней мере, при запуске - вы можете рассуждать об этом лучше.

Кроме того, поскольку вы не изменяете входные данные, вы должны пометить их как const.Это лучше сообщает ваше намерение - и дает проверку во время компиляции того, что вы на самом деле пытаетесь выполнить.Это особенно важно, если вы собираетесь повторно использовать такое имя, как strcat, которое имеет ожидания.(Повторное использование этого имени - это еще одна вещь, которую вы можете пересмотреть.)

char *my_strcat(const char* s1, const char* s2)
{
  char* result = malloc(strlen(s1) + strlen(s2) + 1);

  // To satisfy @P__J__ I will expand on this by saying that
  // Your interface should document what the behavior is when
  // malloc fails and `result` is NULL.  Depending on the
  // overall needs of your program, this might mean returning
  // NULL from my_strcat itself, terminating the program, etc.
  // Read up on memory management in other questions.

  char* dest = result;
  while (*s1 != '\0')
     *dest++ = *s1++;
  while (*s2 != '\0')
      *dest++ = *s2++;
  *dest++ = '\0';
  return result;
}
0 голосов
/ 22 сентября 2018

Вы перемещаете указатель *p сам по себе, следовательно, даже если данные копируются, он (указатель p) уже размещен вперед, поэтому вместо этого выполняется еще один указатель на память:

char *my_strcat(char* s1, char* s2)
{
     char* p = malloc(strlen(s1) + strlen(s2) + 1);
     char *c=p;    //RATHER THAN POINTER P, POINTER C WILL TRAVEL/MOVE
     while (*s1 != '\0')
          *(c++) = *(s1++);
     printf("%s\n\n",p);
     while (*s2 != '\0')
          *(c++) = *(s2++);
     *c = '\0';
     return p;
}

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

0 голосов
/ 22 сентября 2018

Так как вы увеличиваете p в процессе конкатенации.

*p++ = *s1++; 

и

*p++ = '\0'; //don't do p++ here

p будут указывать на то, что после конкатенации будет выделена память.

Просто добавьте один фиктивный указатель, указывающий на начало p, и верните его.

Ниже приведен пример кода.

char *my_strcat(const char* s1,const char* s2)
{
  char *p = malloc(strlen(s1) + strlen(s2) + 1);

  char *start = p;
  if (p != NULL)
  {
       while (*s1 != '\0')
       *p++ = *s1++;
       while (*s2 != '\0')
       *p++ = *s2++;
      *p = '\0';
 }

  return start;
}
...