Look at struct1.c:
#include < stdio.h > #include < string.h > typedef struct { char *fname; char *lname; int age; } Person; print_person(Person *p) { printf("%s %s: Age: %d\n", p->fname, p->lname, p->age); } main() { char line[1000]; Person p; printf("Enter first name: "); if (gets(line) == NULL) exit(0); p.fname = strdup(line); printf("Enter last name: "); if (gets(line) == NULL) exit(0); p.lname = strdup(line); printf("Enter age: "); if (gets(line) == NULL) exit(0); p.age = atoi(line); print_person(&p); }Note the typedef statement. This means that you can use the name Person to access the struct. Otherwise, you'd have to name the struct with something like:
struct person { char *fname; char *lname; int age; };And then you'd name variables such as p with ``struct person p''. If this is not review for you, look at struct1a.c, which is equivalent to struct1.c without the typedef.
Now, struct1 statically allocates one Person struct, and then fills it in with info from standard input. Note I'm using gets() instead of scanf(). This is just a matter of preference -- soon we won't be using either of them.
Then print_person() is called to print out the struct. Note, if I have a struct (such as p in main()), then I access its fields with a dot. If I have a pointer to a struct (such as p in print_person()), then I access its fields with an arrow (->). Note how I called print_person() with the address of p. You should be getting used to this by now.
You will typically be dealing with pointers to structs, so get used to using the arrows rather than the dots.
#include < stdio.h > #include < string.h > typedef struct { char *fname; char *lname; int age; } Person; print_person(int i, Person *p) { printf("Person %3d: %-20s %-20s Age: %3d\n", i, p->fname, p->lname, p->age); } main() { char line[1000]; Person *parray; int n, i; printf("How many people will you enter? "); if (gets(line) == NULL) exit(0); n = atoi(line); if (n <= 0) exit(0); parray = (Person *) malloc(sizeof(Person) * n); for (i = 0; i < n; i++) { printf("Enter first name of person %d: ", i); if (gets(line) == NULL) exit(0); parray[i].fname = strdup(line); printf("Enter last name of person %d: ", i); if (gets(line) == NULL) exit(0); parray[i].lname = strdup(line); printf("Enter age of person %d: ", i); if (gets(line) == NULL) exit(0); parray[i].age = atoi(line); } for (i = 0; i < n; i++) { print_person(i, &(parray[i])); } }Instead of reading in one person , we prompt the user for a number of people to read in, and then we read in that many people. In order to have this work with any number of people, we must use malloc() to allocate an array with the appropriate number of people. Then we fill it in, just as struct1.c. Finally, we traverse the array and print each person. Note how I make the call to print_person(). The following also would have worked:
print_person(i, parray+i);Personally, I like &(parray[i]) because it states more plainly what you're doing, but both ways work.
Also, look at print_person(). I have put field widths into the printf() statement. The format string says to:
UNIX> struct2 How many people will you enter? 3 Enter first name of person 0: Jim Enter last name of person 0: Plank Enter age of person 0: 32 Enter first name of person 1: Brad Enter last name of person 1: Vander Zanden Enter age of person 1: 35 Enter first name of person 2: Katie Enter last name of person 2: Plank Enter age of person 2: 4 Person 0: Jim Plank Age: 32 Person 1: Brad Vander Zanden Age: 35 Person 2: Katie Plank Age: 4 UNIX>Note that by using gets() I was able to handle that two-word last name.
#include < stdio.h > #include < string.h > typedef struct { char *fname; char *lname; int age; } Person; print_person(int i, Person *p) { printf("Person %3d: %-20s %-20s Age: %3d\n", i, p->fname, p->lname, p->age); } main() { char line[1000]; Person **parray, *p; int n, i; printf("How many people will you enter? "); if (gets(line) == NULL) exit(0); n = atoi(line); if (n <= 0) exit(0); parray = (Person **) malloc(sizeof(Person *) * n); for (i = 0; i < n; i++) { p = (Person *) malloc(sizeof(Person)); parray[i] = p; printf("Enter first name of person %d: ", i); if (gets(line) == NULL) exit(0); p->fname = strdup(line); printf("Enter last name of person %d: ", i); if (gets(line) == NULL) exit(0); p->lname = strdup(line); printf("Enter age of person %d: ", i); if (gets(line) == NULL) exit(0); p->age = atoi(line); } for (i = 0; i < n; i++) { print_person(i, parray[i]); } }Each Person struct is now allocated right before being filled in. I think that this code looks cleaner than struct2.c, but of course, individual tastes do vary.