hi guys,

I'm trying to implement a basic program which deals with structures and pointers. I have to insert data for various citizens, which is structure that have other structures as fields.

in this case my main objective is to create 2 general functions that will get the information for each field of the structures. One for the int type and the other for strings. Both functions have 2 arguments, the 1st one is a string that will ask the user the information that we will have to store and the 2nd is the destination of that information.

But these 2 functions are to be used inside other functions that will deal with a specific structure from the "main" structure, in this case CITIZEN.

I noticed that this code work for a single citizen, but I'm not sure if it's totally correct. Also I should generalize this code, let's say to 10 citizens for example. In that case i think I have to create an array of 10 CITIZEN structures and it has to do with pointers and their increment, but i'm not "seeing" how to do it.
if anyone could give me a hand with this I would be very grateful.

Thanks

#include <stdio.h>
#include <string.h>


typedef struct personal_info {

 char name[30];
 int age;
 int height;

}PERSONAL_INFO;

typedef struct info_number {

 int driver_licence;
 int social_security_number;
 int passport;

}INFO_NUMBER;

typedef struct address {

 char street[20];
 int door_number;
 int zip_code;

}ADDRESS;

typedef struct citizen {

 struct personal_info prs_inf;
 struct info_number infnum;
 struct address add;

}CITIZEN;

/* I'm not sure if the 2nd argument should be like this */
void get_str_struct(char *s, char *ptr) { 

 printf("%s",s);
 gets(ptr); /* I know I shouldn't use gets */

}

/* Once again I'm not sure if the 2nd argument should be like this */
void get_int_struct(char *s, int *ptr) { 

 printf("%s", s);
 scanf("%d", ptr);

}

void insert_personal_info(CITIZEN *ptr) {
  
  get_str_struct("Insert Name: ", ptr->prs_inf.name);
  get_int_struct("Insert age: ", &ptr->prs_inf.age);
  get_int_struct("Insert height: ", &ptr->prs_inf.height);

}




main() {

 CITIZEN cit;
 insert_personal_info(&cit);
 printf("Name = %s", cit.prs_inf.name);
 printf("Age = %d", cit.prs_inf.age);
 printf("Height = %d", cit.prs_inf.height);
 
}

This program is well organized, a good example for others using this forum. It has readable field names (such as "address"), and short, well defined functions that can be improved later without rewriting everything else. And I don't see any errors in the logic.

It makes assumptions (array sizes, etc), which is OK for homework.

I agree it is a good idea to accept more than one citizen. An array[10] of structures is a simple way to do that, but the program should avoid putting 11 items into it.

I noticed that this code work for a single citizen, but I'm not sure if it's totally correct. Also I should generalize this code, let's say to 10 citizens for example. In that case i think I have to create an array of 10 CITIZEN structures and it has to do with pointers and their increment, but i'm not "seeing" how to do it.
if anyone could give me a hand with this I would be very grateful.

No need to play with incrementing pointers yet.

/*
 * main should explicitly return an int
 * notice the int, the void and the return
 * at the end
 */ 
int main(void) {

 CITIZEN cit[10];   /* Who ordered ten cits? Coming right up! */ 
 int x, size;       /* x to track the current cit */
 size = sizeof cit / sizeof (*cit); /* ensures always the right count */

/*
 * process the cit one by one
 * notice the use of size to get the next subscript of cit
 * and for loop control
 */
for (x = 0; x < size; x++) {
     insert_personal_info(&cit[x]);
     /* display can be here or outside in another loop after */
     display_cit(&cit[x]); 
 }
 return 0;
}

/* a possible implementation of display_cit() shown above */
void display_cit (CITIZEN *individual)
{
    /* added a break line for clarity */
    printf("Name = %s\n", individual->prs_inf.name);
    printf("Age = %d\n", individual->prs_inf.age);
    printf("Height = %d\n", individual->prs_inf.height);  
}

Of course, your choice of scanf() to read an int is going to show up its ugly face, leaving behind the ENTER to be picked up by the next read.

After that, you can start learning how to return in your functions, for extra functionally.

Edited 6 Years Ago by Aia: n/a

Yes, as demonstrated by Aia, you do not need to deal with incrementing pointers yet. You may pass in the address of a particular CITIZEN object

display_cit(&cit[x]);

Then create a pointer as parameter to be able to access the passed in object's value

void display_cit (CITIZEN *individual)

The pointer version is fairly simple,too:

CITIZEN *cit_ptr = &cit[0];
for (x = 0; x < size; x++, cit_ptr++) {
  insert_personal_info(cit_ptr);
  display_cit(cit_ptr);
}
This question has already been answered. Start a new discussion instead.