简体   繁体   中英

Why my program won't show each element with printf();?

I made a very tiny program which actually allows you to create N families with X members and when I try to display "ALL" members from all families I can't, it will only display last family members. Why and how to fix it?

.....................................................................................................................................................................

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

struct family {
    int size;
    struct person *member;
    char address[256];
};

struct person {
   int age;
   char name[30];
};

int main(){
   struct family *member;
   struct person *ptr;
   int j,k;
   int i,n;
   printf("\nEnter family count: ");
   scanf("%d",&j);

   for(k=0;k<j;k++){
      member=(struct family*)malloc(j*sizeof(struct family));


      printf("Enter family member count: ");
      scanf("%d",&n);


      ptr=(struct person*)malloc(n*sizeof(struct person));
      for(i=0;i<n;++i){
         printf("\nEnter person and the age:\n");
         scanf("%s%d",&(ptr+i)->name, &(ptr+i)->age);
      }
   }
   printf("\nDisplaying Infromation:\n");
   for(i=0;i<n;++i)
      printf("%s\t%d\t\n",(ptr+i)->name,(ptr+i)->age);
   _getch();
   return 0;
}

These lines:

for(k=0;k<j;k++){
   member=(struct family*)malloc(j*sizeof(struct family));

make sure that only the last member is retained when the loop ends.

This line

  ptr=(struct person*)malloc(n*sizeof(struct person));

makes sure that only the last ptr is retained when the loop ends.

What you need is something like:

int main(){
   struct family *family_array = NULL;
   int j,k;
   int i,n;

   printf("\nEnter family count: ");
   scanf("%d",&j);

   // Allocate memory for j families.
   family_array = malloc(j*sizeof(struct family));

   // Read the data for each family.
   for(k=0;k<j;k++){

      printf("Enter family member count: ");
      scanf("%d",&n);

      // Make sure to store the size of the family.
      family_array[k].size = n;

      // Allocate memory for the members of the family.
      family_array[k].member = malloc(n*sizeof(struct person));

      // Read the data for each member of the family.
      for(i=0;i<n;++i){
         printf("\nEnter person and the age:\n");
         scanf("%s%d",family_array[k].member[i].name, &(family_array[k].member[i].age));
      }
   }

   printf("\nDisplaying Infromation:\n");
   for(k=0;k<j;k++)
   {
      n = family_array[k].size;
      for(i=0;i<n;++i)
      {
         printf("%s\t%d\t\n", family_array[k].member[i].name, family_array[k].member[i].age);
      }
   }

   // Make sure to deallocate the memory.
   for(k=0;k<j;k++)
   {
      free(family_array[k].member);
   }
   free(family_array);

   _getch();
   return 0;
}

PS It will be good to add error checking code any time you use scanf . It's not a good practice to assume that the user always provides good input.

I fixed your code, the problems I found were

  1. The first allocation, for the struct family *member is wrong, because it should be performed before the loop

     member=(struct family*)malloc(j*sizeof(struct family)); for (k = 0 ; k < j ; k++) ... 
  2. You never use the allocated struct family *member; it should be used to store the members of the family, that's why I renamed it to family , so you have a member size in that struct, that's where scanf for the member count should store the value

     printf("Enter family member count: "); scanf("%d", &member[k].size); 

    now the value is stored at the size member so the next loop should go like

     for (j = 0 ; j < member[k].size ; j++) 

    and the malloc , before the loop should be

     member[k].member = malloc(member[k].size * sizeof(struct person)); 
  3. Your scanf for the name is wrong, you should not take the address of the array

     scanf("%s%d",&(ptr+i)->name, &(ptr+i)->age); -> scanf("%s%d",(ptr+i)->name, &(ptr+i)->age); 

    but according to the previously mentioned issues you should do it this way

     scanf("%s%d", member[k].memberj].name, &member[k].member[j].age); 

    after all this is fixed you can output the data iterating over all member elements and all member->member elements.

Here is the fixed code

struct family 
{
    int size;
    struct person *member;
    char address[256];
};

struct person 
{
int age;
char name[30];
};

int main()
{
    struct family *family;
    int familyCount, i, j;

    printf("\nEnter family count: ");
    scanf("%d", &familyCount);

    family = malloc(familyCount * sizeof(*family));
    for (i = 0 ; i < familyCount ; i++)
    {
        printf("Enter family member count: ");
        scanf("%d", &family[i].size);

        family[i].member = malloc(family[i].size * sizeof(*(family[i].member)));
        for (j = 0 ; j < family[i].size ; ++j)
        {
            printf("\nEnter person and the age:\n");
            scanf("%s%d", family[i].member[j].name, &family[i].member[j].age);
        }
    }

    for (i = 0 ; i < familyCount ; ++i)
    {
        printf("Family %d:\n", 1 + i);
        for (j = 0 ; j < family[i].size ; ++j)
            printf("\tmember %d: %s, %d\n", 1 + j, family[i].member[j].name, family[i].member[j].age);
    }

    return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM