Как я могу добавить символ в строку, динамически распределяя память в C? - PullRequest
0 голосов
/ 01 октября 2018

Я написал этот код, но вставил мусор в начало строки:

void append(char *s, char c) {
    int len = strlen(s);
    s[len] = c;
    s[len + 1] = '\0';
}

int main(void) {
    char c, *s;
    int i = 0;
    s = malloc(sizeof(char));
    while ((c = getchar()) != '\n') {
        i++;
        s = realloc(s, i * sizeof(char));
        append(s, c);
    }   
    printf("\n%s",s);   
}

Как я могу это сделать?

Ответы [ 3 ]

0 голосов
/ 01 октября 2018

В вашем коде несколько проблем:

  • вы выполняете итерацию до тех пор, пока не прочитаете новую строку ('\n') из стандартного потока ввода.Это приведет к бесконечному циклу, если перед прочтением новой строки произойдет конец файла, что произойдет, если вы перенаправите стандартный ввод из пустого файла.
  • c следует определить как int, чтобы вы моглипроверять правильность EOF.
  • s должен всегда завершаться нулем, вы должны установить первый байт на '\0' после malloc(), так как эта функция не инициализирует память, которую она выделяет.
  • i следует инициализировать на 1, поэтому первый realloc() расширяет массив на 1 и т. Д. В кодированном виде ваш массив на один байт слишком короток, чтобы вместить дополнительный символ.
  • вы должны проверить на наличие ошибки выделения памяти.
  • для хорошего стиля, вы должны освободить выделенную память перед выходом из программы
  • main() должен вернуть int, предпочтительно 0 для успеха.

Вот исправленная версия:

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

/* append a character to a string, assuming s points to an array with enough space */
void append(char *s, char c) {
    size_t len = strlen(s);
    s[len] = c;
    s[len + 1] = '\0';
}

int main(void) {
    int c;
    char *s;
    size_t i = 1;
    s = malloc(i * sizeof(char));
    if (s == NULL) {
        printf("memory allocation failure\n");
        return 1;
    }
    *s = '\0';
    while ((c = getchar()) != EOF && c != '\n') {
        i++;
        s = realloc(s, i * sizeof(char));
        if (s == NULL) {
            printf("memory allocation failure\n");
            return 1;
        }
        append(s, c);
    }
    printf("%s\n", s);
    free(s);
    return 0;
}
0 голосов
/ 01 октября 2018

Внутреннему realloc нужно выделить еще один элемент (для конечного \0), и вам нужно инициализировать s[0] = '\0' перед началом цикла.

Кстати, вы можете заменить appendstrcat() или напишите как

size_t i = 0;
s = malloc(1);
/* TODO: check for s != NULL */
while ((c = getchar()) != '\n') {
        s[i] = c;
        i++;
        s = realloc(s, i + 1);
        /* TODO: check for s != NULL */
}
s[i] = '\0';
0 голосов
/ 01 октября 2018

когда вы вызываете strlen, он ищет символ '\0', чтобы завершить строку.У вас нет этого символа внутри вашей строки, поэтому поведение strlen непредсказуемо.Ваша append функция действительно хороша.Кроме того, незначительная вещь, вам нужно добавить return 0; в вашу основную функцию.И i должен начинаться с 1 вместо 0, вот как это должно выглядеть:

int main(void){
   char *s;
   size_t i = 1;
   s = malloc (i * sizeof(char));//Just for fun. The i is not needed.
   if(s == NULL) {
   fprintf(stderr, "Coul'd not allocate enough memory");
   return 1;
   }
   s[0] = '\0';
   for(char c = getchar(); c != '\n' && c != EOF; c = getchar()) {//it is not needed in this case to store the result as an int.
      i++;
      s = realloc (s,i * sizeof(char) );
      if(s == NULL) {
             fprintf(stderr, "Coul'd not allocate enough memory");
             return 1;
      }
      append (s,c);
    }   
printf("%s\n",s);   
return 0;
}

Спасибо за комментарии, которые помогли мне улучшить код (и мой английский).Я не идеален:)

...