2

I'm trying to make a simple program to ask for user input (name and age) using a structure and allocating memory. I start with an array of 2 spaces, however when i try to assign more it overwrite the previous input.

Can someone show me where i'm being wrong?

#include <stdio.h>
#include <stdlib.h>
#include <stdio_ext.h>
typedef struct
{
    char nombre[20];
    int edad;
}Persona;

int main()
{
    int sizeArrayPersonas = 2;
    Persona listaPersonas[sizeArrayPersonas];
    Persona* pArrayPersona = NULL;
    char respuesta = 's';

    int i;

    pArrayPersona = listaPersonas;


    while(respuesta == 's')
    {
        pArrayPersona = (Persona*)malloc(sizeof(Persona)*sizeArrayPersonas);
        for(i=0;i<sizeArrayPersonas;i++)
        {
            printf("Ingrese nombre: ");
            __fpurge(stdin);
            fgets((pArrayPersona+i)->nombre,20,stdin);

            printf("Ingrese edad: ");
            scanf("%d", &(pArrayPersona+i)->edad);
        } 

        printf("Desea ingresar otro usuario? (s o n): ");
        __fpurge(stdin);
        scanf("%c", &respuesta);

        if(respuesta == 's')
        {
            Persona* pAuxArray;
            pAuxArray = (Persona*)realloc(pArrayPersona,sizeof(Persona)*(sizeArrayPersonas+1));
            if(pAuxArray != NULL)
            {
                pArrayPersona = pAuxArray;
                sizeArrayPersonas++;
                pAuxArray = NULL;   
            }
        }
    }

    //Mostrar array de estructura 
    for(i=0;i<sizeArrayPersonas;i++)
    {
        printf("Nombre: %s Edad: %d \n", (pArrayPersona+i)->nombre, (pArrayPersona+i)->edad);
    }

    return 0;
}
Villano
  • 47
  • 1
  • 5
  • What part of the code is not working? Try to provide as much information as possible. The better the question, the better the answer. – DarkAtom May 28 '20 at 20:45
  • Also, please don't cast the result of `malloc()` and friends. https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc – DarkAtom May 28 '20 at 20:47
  • After i input the two firsts users and i tell the program i want to input more, it asks me three more times for info and overwrites the initial data. I want that after telling the program to ask for another input, ask me one more time and print a new user with the initial two – Villano May 28 '20 at 20:55
  • in `pArrayPersona = listaPersonas; pArrayPersona = (Persona*)malloc(sizeof(Persona)*sizeArrayPersonas);`, what is the purpose of the first assignment? – William Pursell May 28 '20 at 22:47

1 Answers1

1

when i try to assign more it overwrite the previous input.

Because in your code below:

for(i=0;i<sizeArrayPersonas;i++)
{
      printf("Ingrese nombre: ");
       __fpurge(stdin);
      fgets((pArrayPersona+i)->nombre,20,stdin);

      printf("Ingrese edad: ");
      scanf("%d", &(pArrayPersona+i)->edad);
} 

You always input the value for pArrayPersona from 0 to sizeArrayPersonas - 1

In the next iteration, you have to input value for pArrayPersona[sizeArrayPersonas], it means the value of old sizeArrayPersonas+1_th elements (for example, in first iteration you input 2 values, then in the next iteration, after type s, you have to input for 3rd element, you do not need to re-enter the value of 1st and 2nd elements of pArrayPersona).

Your code in if condition can change it to:

Persona* pAuxArray = realloc(pArrayPersona,sizeof(Persona)*(sizeArrayPersonas+1));
if(pAuxArray == NULL) {
   free(pArrayPersona);
   return -1;
} else {
   pArrayPersona = pAuxArray;
   sizeArrayPersonas++;
}

You have to malloc for pArrayPersona before while loop instead of at the beginning of the while loop.

BTW, your while loop can be:

    int i = 0;
    pArrayPersona = malloc(sizeof(Persona)*sizeArrayPersonas);
    while(respuesta == 's')
    {
        for( ;i<sizeArrayPersonas;i++)
        {
            printf("Ingrese nombre: ");
            fgets((pArrayPersona+i)->nombre,20,stdin);

            printf("Ingrese edad: ");
            scanf("%d", &(pArrayPersona+i)->edad);
        }

        printf("Desea ingresar otro usuario? (s o n): ");
        scanf(" %c", &respuesta);

        if(respuesta == 's')
        {
            Persona* pAuxArray = realloc(pArrayPersona,sizeof(Persona)*(sizeArrayPersonas+1));
            if(pAuxArray == NULL) {
                free(pArrayPersona);
                return -1;
            } else {
                pArrayPersona = pAuxArray;
                sizeArrayPersonas++;
            }
        }
    }

Do not forget to free(pArrayPersona); at the end of program (when you do not need to use it).

Hitokiri
  • 3,607
  • 1
  • 9
  • 29
  • 1
    @RichardChambers Thank for your comment. I updated the answer. – Hitokiri May 28 '20 at 22:35
  • 1
    Your comment "You allocate for pAuxArray then assign it to NULL, why do you want to erase all data at the address that pointer points to ?" is misleading. Assigning NULL to a pointer does not erase data pointed to by the pointer. It merely assigns NULL to the pointer variable. The reason for assigning NULL to the pointer is because the new pointer value is being moved to the variable `pArrayPersona` so the user wants to set the temporary pointer variable to NULL since the value it previously held is being held by `pArrayPersona` instead. The temporary pointer is intended only with `realloc()`. – Richard Chambers May 28 '20 at 22:51
  • Previous solution wasn't working. But this one is perfect, just what i was looking, thank you. The free() function was the one i was skipping – Villano May 28 '20 at 22:54
  • 1
    An improvement would be to initialize `pArrayPersona` to NULL before the `while` loop and to move the code within the `if(respuesta == 's')`, keeping the braces but removing the `if`, taking advantage that `realloc()` operates like `malloc()` if the pointer is NULL. Initialize `sizeArrayPersonas` with 0. It looks to me that there is an unused element to the array pointed to by `pArrayPersona` and then the question is why the `for` loop within the `while` loop? – Richard Chambers May 29 '20 at 13:44
  • @RichardChambers `why the for loop within the while loop?` because the OP want to input `sizeArrayPersonas (2)` elements first (see the definition: `int sizeArrayPersonas = 2`). It's also the reason why i allocated the `pArrayPersona` before `while` loop instead of initializing `pArrayPersona` by `0`. – Hitokiri May 29 '20 at 16:57
  • if OP changes the initialization to `sizeArrayPersonas = 0` we can use the `realloc` function at the beginning of `while` loop (in this case, we can initialize `pArrayPersona` by `0` (`NULL`) as you said in your comment). Of course, if OP want to input element by element, we can do as you said. OT, for the improvement, there are still many thing to do, for example, check the return of `scanf`, check the input of `ch` (uppercase, lowercase),etc. We can not improve all. ANY, thanks for your comment. – Hitokiri May 29 '20 at 16:57