/* * linkList.c * create, initialize, and free a simple Linked List * of dynamic structs */ #include #include #include #define MAX_NAME_LENGTH 10 typedef struct { char *name; int age; } Person; /* Person is now a data type */ /* typedef struct list_node * ListNodePtr; */ typedef struct list_node { Person data; struct list_node *next; } ListNode; /* ListNode is another data type */ void printList(ListNode *hd); void freeList(ListNode *hd); void fatalError(char *msg); int main(int argc, char *argv[]) { FILE *inFile; ListNode *head = NULL; ListNode *tmp; /* doubles for new element pointer and iterator */ /* temp variables to read data from file */ char name[MAX_NAME_LENGTH]; int age; if (!(inFile = fopen("input.txt", "r"))) fatalError("Can't open input.txt"); /* Build list via insert at front with each name/age from infile */ while(fscanf(inFile,"%s %d",name,&age) == 2) { if ((tmp = (ListNode *)malloc(sizeof(ListNode))) == NULL) fatalError("malloc of tmp failed"); if ((tmp->data.name = (char *)malloc((strlen(name) + 1) * sizeof(char))) == NULL) fatalError("malloc of tmp->name failed"); strcpy(tmp->data.name,name); tmp->data.age = age; /* insert the new node in front of the current head node */ tmp->next = head; head = tmp; } fclose(inFile); printf("printing the list:\n"); printList(head); freeList(head); return 0; } /* Notice we use our incoming head pointer as an iterator! * We are not corrupting the real head in main - this is just a copy * Some folks like this style, some would rather use an explicit temp ptr */ void printList(ListNode *hd) { for ( ; hd != NULL; hd = hd->next) { printf("[%s,%d]", hd->data.name, hd->data.age); if (hd->next) printf(" -> "); } printf("\n"); } /* use recursion to free string and struct on the way back up the list. * Doing this going forward would be cutting our bridge off in front of us */ void freeList(ListNode *hd) { if (hd == NULL) return; freeList(hd->next); /* recurse to the end of list */ free(hd->data.name); /* free the string */ free(hd); /* then the struct */ } /* a convenient function to print a fatal error msg and exit the program * Note we don't bother cleaning up memory. It will be done for us * when our program exits. */ void fatalError(char *msg) { fprintf(stderr,"\nFATAL ERROR: %s!!\n\n", msg); exit(EXIT_FAILURE); }