0

I'm trying to write a program that dynamically increases a char array. When I print the array, it increments the array, but old data is overwritten with whatever the user inputs and duplicates that input each time. Can someone please help me?

Desired output:

Item1
Item2
Item3

Current output:

Item3
Item3
Item3

Here is my code:

int main()
{
    int length = 1;
    char *list;
    list = calloc(length, length * sizeof(char *));

    char *temp;
    char user_input[100];

    while (1) {
        fgets(user_input, 100, stdin);
        user_input[strcspn(user_input, "\n")] = 0;

        temp = realloc(list, length * sizeof(char));

        strcpy(temp, user_input);

        list = temp;

        printf("****LIST****\n\n");
        for (int item = 0; item < length; item++) {
            puts(list);
        }
        printf("\n");

        length++;
    }
    return 0;
}
chqrlie
  • 131,814
  • 10
  • 121
  • 189
  • 1
    `length *sizeof(char *)` makes no sense as `list` is `char *` – Jean-François Fabre Jul 11 '22 at 21:19
  • 3
    more importantly looping to print the same `list` pointer obviously prints several times the same thing... this code is a mess, sorry – Jean-François Fabre Jul 11 '22 at 21:21
  • 2
    `temp = realloc(list,length*sizeof(char))` You never increased `length`, so this isn't enough to hold the user input. You need `length = strlen(user_input)+1` first. – Barmar Jul 11 '22 at 21:22
  • @Jean-FrançoisFabre Do you ever feel like up-voting just because they used `fgets()` instead of `gets()`? :) – Barmar Jul 11 '22 at 21:23
  • 1
    You're printing the whole list for each iteration of the while loop. I don't see how it can print what you say it's printing. – Jeff Holt Jul 11 '22 at 21:24
  • @Barmar and also `strcspn`. Someone read stackoverflow answers... – Jean-François Fabre Jul 11 '22 at 21:24
  • @hecomputerguru The program contains so much senseless code that the question should be closed. You need to rewrite the program. – Vlad from Moscow Jul 11 '22 at 21:24
  • Is `list` supposed to hold multiple to-do items, or just the current item being read? – Barmar Jul 11 '22 at 21:25
  • @Barmar Multiple items. – thecomputerguru Jul 11 '22 at 21:25
  • @Jean-FrançoisFabre Sorry for the messy code, I was honestly getting a little frustrated trying to figure this out. – thecomputerguru Jul 11 '22 at 21:26
  • `strcpy` overwrites the previous data. You probably want `strcat`, but the code has many other issues. – William Pursell Jul 11 '22 at 21:28
  • You have no way of getting out the loop in the question's code. You should be using `while (fgets(user_input, sizeof(user_input), stdin) != 0)` to control the loop (and remove the `fgets()` in the loop, of course). You need to error check memory allocations. IMO, the type of `list` should be `char **` and you then need to allocate space to copy the input line, and the `realloc()` needs to use `(length + 1)` (at least), and `sizeof(char *)` not `sizeof(char)`. There's more that should probably be fixed. – Jonathan Leffler Jul 11 '22 at 22:08
  • This (and almost everything else) would be a lot easier in C++, have you considered [learning it](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list)? – Paul Sanders Jul 11 '22 at 22:47

1 Answers1

2

list should be char ** since it's an array of strings, not a single string.

You need to allocate a separate string for each list item, to hold a copy of that line.

int main()
{
  int length = 0;
  char **list = NULL;

  char user_input[100];

  while(1)
  {
    fgets(user_input,sizeof user_input,stdin);
    user_input[strcspn(user_input,"\n")] = 0;

    char *temp = malloc(strlen(user_input) + 1);
    if (!temp) {
        printf("Unable to allocate input string\n");
        exit(1);
    }
    strcpy(temp,user_input);

    length++;
    char **temp_list = realloc(list, length * sizeof(*temp_list));
    if (!temp_list) {
        printf("Unable to realloc list\n");
        exit(1);
    }
    list = temp_list;
    list[length-1] = temp;

    printf("****LIST****\n\n");
    for(int item = 0;item < length;item++)
    {
      printf("%s\n", list[item]);
    }
    printf("\n");

  }
   return 0;
}
Barmar
  • 741,623
  • 53
  • 500
  • 612