Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * for: https://stackoverflow.com/a/66997713/3422102
- *
- * example inut file:
- John 12345
- Sam 54321
- Daivd 1000
- Mike 5391
- Lion 43222
- Phil 8332
- Bill 2853
- *
- * then:
- *
- * add (&list, "Zylon", "12");
- *
- * defines:
- * DEBUG - output: "previous current next" pointers for each node
- *
- */
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #define NAMENUM 20
- typedef struct person {
- char *firstName,
- *age;
- struct person *previous,
- *next;
- } Person;
- void print (Person* list)
- {
- while (list) {
- printf ("%s %s\n",list->firstName,list->age);
- list = list->next;
- }
- }
- void prnptrs (Person *list)
- {
- while (list) {
- printf ("%p %p %p\n", (void*)list->previous, (void*)list, (void*)list->next);
- list = list->next;
- }
- }
- void reverseList (Person **list) {
- Person *current = *list;
- Person *last = current;
- if (!current || !current->next)
- return;
- do {
- Person *temp = current->previous;
- current->previous = current->next;
- current->next = temp;
- last = current;
- } while ((current = current->previous));
- *list = last;
- }
- Person *createnode (const char *firstName, const char *age)
- {
- size_t len;
- Person *node = malloc (sizeof *node); /* allocate node, use dereference ptr for size */
- if (!node) { /* validate EVERY allocation */
- perror ("malloc-node");
- return NULL;
- }
- node->next = node->previous = NULL; /* initialize next and previous NULL */
- len = strlen (firstName); /* get length of firstName */
- if (!(node->firstName = malloc (len + 1))) { /* allocate/validate */
- perror ("malloc-node->firstName");
- free (node); /* free node before return */
- return NULL;
- }
- memcpy (node->firstName, firstName, len + 1); /* copy firstName to node */
- len = strlen (age); /* get length of age */
- if (!(node->age = malloc (len + 1))) { /* allocate/validate */
- perror ("malloc-node->age");
- free (node->firstName); /* free node->firstName, and */
- free (node); /* free node before return */
- return NULL;
- }
- memcpy (node->age, age, len + 1); /* copy age to node */
- return node;
- }
- /* add node to list using address of list and pointer to list
- * returns pointer to new node on success, NULL otherwise.
- */
- Person *add (Person **list, const char *firstName, const char *age)
- {
- Person **ppn = list, /* address of list */
- *pn = *list, /* pointer to list */
- *node = createnode (firstName, age); /* initialize & validate new node */
- if (!node) /* node creation failed, return list */
- return NULL;
- while (pn) { /* loop over each node */
- if (strcmp (firstName, pn->firstName) <= 0) { /* compare sorts before pn->firstName */
- node->previous = (*ppn)->previous; /* if so, insert new before pn */
- node->next = pn;
- pn->previous = node;
- *ppn = node; /* update node at address of current node to new node */
- return node;
- }
- if (!pn->next) { /* if pn is last node, insert at end */
- pn->next = node;
- node->previous = pn;
- break;
- }
- ppn = &pn->next; /* advamce address to address of next node */
- pn = pn->next; /* advance pointer to next */
- }
- return pn ? node : (*list = node); /* if not 1st node, return node, else *list=node */
- }
- /** delete node where firstName equals name
- * returns 1 if node found/deleted, 0 otherwise
- */
- int delete (Person **list, const char *name)
- {
- if (!*list) { /* list-empty */
- puts ("List Empty");
- return 0; /* return 0 - no replacement */
- }
- Person **ppn = list, /* address of node (pointer-to-pointer-to-node) */
- *pn = *list; /* pointer to node */
- for (; pn; ppn = &pn->next, pn = pn->next) { /* loop over all nodes */
- if (strcmp (pn->firstName, name) == 0) { /* if node with name found */
- *ppn = pn->next; /* replace node at current address with next */
- if (pn->next) /* if not last node (*ppn now NULL) */
- (*ppn)->previous = pn->previous; /* update node at address w/exiting previous */
- free (pn->firstName); /* free all memory for existing node */
- free (pn->age);
- free (pn);
- return 1; /* return 1 - replacement made */
- }
- }
- fprintf (stderr, "warning: name not found '%s'.\n", name);
- return 0;
- }
- /** delete all nodes in list */
- void del_list (Person *list)
- {
- while (list) {
- Person *victim = list;
- list = list->next;
- free (victim->firstName);
- free (victim->age);
- free (victim);
- }
- }
- int main (int argc, char **argv) {
- char name[NAMENUM], num[NAMENUM];
- Person *list = NULL;
- /* use filename provided as 1st argument (stdin by default) */
- FILE *in = argc > 1 ? fopen(argv[1], "r") : stdin;
- if (!in) { /* validate file open for reading */
- perror ("fopen-in");
- return 1;
- }
- while (fscanf (in, "%s %s",name, num) == 2)
- add (&list, name, num);
- fclose (in);
- add (&list, "Zylon", "12");
- printf ("Original List\n***\n");
- print (list);
- #ifdef DEBUG
- puts ("\nPointers\n***");
- prnptrs (list);
- #endif
- printf ("\nReversed List\n***\n");
- reverseList(&list);
- print (list);
- puts ("\nRemoving Bill, Phil, Sam, bananas from reversed list\n***");
- delete (&list, "Bill");
- delete (&list, "Phil");
- delete (&list, "Sam");
- delete (&list, "bananas");
- print (list);
- del_list (list); /* free all allocated memory */
- return 0;
- }
- /*
- Example Input File:
- $ cat dat/ypzgttvk.txt
- John 12345
- Sam 54321
- Daivd 1000
- Mike 5391
- Lion 43222
- Phil 8332
- Bill 2853
- Example Use/Output
- $ ./bin/ll_reverse_ptp dat/ypzgttvk.txt
- Original List
- ***
- Bill 2853
- Daivd 1000
- John 12345
- Lion 43222
- Mike 5391
- Phil 8332
- Sam 54321
- Zylon 12
- Reversed List
- ***
- Zylon 12
- Sam 54321
- Phil 8332
- Mike 5391
- Lion 43222
- John 12345
- Daivd 1000
- Bill 2853
- Removing Bill, Phil, Sam, bananas from reversed list
- ***
- warning: name not found 'bananas'.
- Zylon 12
- Mike 5391
- Lion 43222
- John 12345
- Daivd 1000
- */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement