Member 13592362 Ответов: 2

Сделайте функцию более простой


Мне было интересно, могу ли я сделать функцию "strinsert" в этом коде более простой или короткой.

Что я уже пробовал:

int strinsert(char *dst, int len, const char *src, int offset)
{
  char leng[len];
  int i, j=0, x=0;
  if (strlen(src)+strlen(dst)>len-1 || offset>strlen(dst))
    return 1;
  else
  {
    for (i=0; strlen(dst)+strlen(src)>=i; i++)
    {
      if (i<offset)
      {
        leng[i]=dst[i];
        x++;
      }
      else if (j<strlen(src))
      {
        leng[i]=src[j];
        j++;
      }
      else if (j<strlen(src)+strlen(dst))
      {
        leng[i]=dst[x];
        x++;
      }
    }
  leng[strlen(leng)]='\0';
  strcpy(dst,leng);
  return 0;
  }
}

int main()
{
  char dst[100], src[100];
  int len, offset;
  scanf("%s %d %s %d", dst, &len, src, &offset);

  if (strinsert(dst, len, src, offset))
    printf("Failed\n");
   else
    printf("%s", dst);
  return 0;
}

Patrice T

Что должно выполнять эту функцию?
Есть ли примеры ввода и вывода?

2 Ответов

Рейтинг:
1

OriginalGriff

Вот что самое интересное: Мне не нравится этот код.
Это последний бит, который говорит мне "нет!" :

strcpy(dst,leng);
Ленг определяется как размер выходных данных - но нет никакой гарантии, что dst имеет столько места - и поскольку вы вставляете кусок данных в середину исходного содержимого dst, почти наверняка он будет длиннее, чем был t, что означает, что он вполне может превышать пространство, выделенное для него. Если это произойдет, ваш код перезапишет последующие данные.
Лучшим подходом было бы использовать malloc для выделения области вывода и возврата ее из вашей функции вместо перезаписи оригинала.

Есть также польза от strlen не понимая, что он делает: он подсчитывает символы до первого нуля и возвращает этот счет.
Так почему же вы используете его для определения местоположения, чтобы поместить завершающий нуль?
leng[strlen(leng)]='\0';
По определению, в этом месте уже есть нуль...
Это также медленная операция - поэтому использовать ее дважды каждый раз, когда вы обходите петлю, ужасно неэффективно, учитывая, что ни то, ни другое src ни dst получить изменения внутри цикла.

Я бы сделал это так:
1) malloc достаточно места, чтобы держать выход.
2) Использовать memcpy, чтобы скопировать первую часть летнего времени закончится.
3) Используйте memcpy для копирования src.
4) использовать memcpy, чтобы скопировать в конец DST за.
5) возвращает новую строку.

Это также означает, что вы можете объявить его как
char *strinsert(const char *dst, int len, const char *src, int offset)

Это означает, что вы можете передавать постоянные строки в функцию. И это будет намного быстрее!


Рейтинг:
1

W∴ Balboos, GHB

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

int srcLen = strlen(src);
int dstLen = strlen(src);
В качестве хорошего эмпирического руководства, если вы вызываете одну и ту же функцию в ситуации, когда его возвращаемое значение не будет меняться между вызовами, вызов его более одного раза почти наверняка менее эффективен и удобочитаем, чем присвоение возвращаемого значения символу и его использование.