title: C - LinkedList Sorting Infinite Loop
body: <p>I am creating a program that will read a word from a text file in main.c, and send it over to list.c file to create a new node to store that word. The node will also store three ints: first (number of times this word appears in txt file 1), second(number of times this word appears in txt file 2), and dif (abs(first-second)). After adding all the new words to the file and counting the number of times each word exists in each txt file, the main.c will call a method that will calculate the difference between first and second for each node. This is difference (stored in dif for each node) will be used to sort the linked nodes in decreasing order. </p>
  
  <p>EX. word: the, first: 2888, second: 2466, dif: 422.
            red,        39            12         27
            .....</p>
  
  <p>However, when main calls the sort method, a infinite loop occurs. This infinite loop comes from the inner loop of the sorting algorithm, where the current node is assigned the node from the curr->next pointer. Somewhere during the sort method, the current node's next pointer points to the current node, not the actual next node in the linkedlist. If the sort method is dactivated, then all other functions work fine, including printAll which goes through the entire list and prints the data in each node (see my example above).</p>
  
  <p>My issue is that I cannot find where in my sort method how current->next started to point to the current node. Any help is appreciated!</p>
  
  <pre><code>/*
   * list.h
   */
  
  #ifndef LIST_H_
  #define LIST_H_
  
  typedef struct node Node;
  
  void findWord(char *word, int book);
  void addWord(char *word, int book);
  void editWord(Node **endPtr, int book);
  void sort();
  void swap(Node **a, Node **b);
  void calculateDiff();
  void printAll();
  
  
  #endif /* LIST_H_ */
  
  
  
  
  /*
   * list.c
   */
  #include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;string.h&gt;
  #include "list.h"
  
  typedef struct node{
      int first;
      int second;
      int dif;
      char name[20];
      struct node *next;
  }Node;
  
  Node *front = NULL;
  
  /*
   * Sees if the current word exists in the
   * linkedlist.
   */
  void findWord(char *word, int book) {
      Node *curr = front;
      int boolean = 0;
  
      while (curr != NULL) {
          if(strcmp(curr-&gt;name, word) == 0) {
              boolean = 1;
              editWord(&amp;curr, book);
              break;
          }
          curr = curr-&gt;next;
  
      }
  
      if(!boolean) { //Add word if it does not exist.
          addWord(word, book);
      }
  }
  
  /*
   * Creates a new node for the added word. Adds to front.
   */
  void addWord(char *word, int book) {
      Node *newNode = malloc (sizeof(Node));
  
      /*
       * Since this word is being added
       * to the linkedlist with a newly
       * created node, either the
       * first or second int must be to 1
       * while the other is set to 0. Based
       * off of book int.
       */
      if(book == 1) {
          newNode-&gt;first = 1;
          newNode-&gt;second = 0;
      } else {
          newNode-&gt;first = 0;
          newNode-&gt;second = 1;
      }
  
      newNode-&gt;dif = 0;
      strcpy(newNode-&gt;name, word);
  
      newNode-&gt;next = front;
      front = newNode;
  
  }
  
  /*
   * Edits the data for an existing word.
   * Only called if current word exists in
   * the linkedlist.
   */
  void editWord(Node **endPtr, int book) {
      if (book == 1) {
          (*endPtr)-&gt;first++;
      } else {
          (*endPtr)-&gt;second++;
      }
  }
  
  /*
   * Sorts the list in descending order based on
   * difference value.
   */
  void sort() {
      Node *curr, *last = NULL;
      curr = front;
  
      while (curr != last) {
          while (curr-&gt;next != last) {
              if(curr-&gt;dif &lt; curr-&gt;next-&gt;dif ) {
                  swap(&amp;curr, &amp;curr-&gt;next);
              }
              curr = curr-&gt;next;
          }
          last = curr;
          curr = front;
      }
  }
  
  /*
   * Swaps the data in the current and next node in the list.
   */
  void swap(Node **a, Node **b) {
      int temp;
      char nameTemp[20];
  
  
      //Swap first
      temp = (*a)-&gt;first;
      (*a)-&gt;first = (*b)-&gt;first;
      (*b)-&gt;first = temp;
  
      //Swap second
      temp = (*a)-&gt;second;
      (*a)-&gt;second = (*b)-&gt;second;
      (*b)-&gt;second = temp;
  
      //Swap dif
      temp = (*a)-&gt;dif;
      (*a)-&gt;dif = (*b)-&gt;dif;
      (*b)-&gt;dif = temp;
  
      //Swap name
      strcpy(nameTemp, (*a)-&gt;name);
      strcpy((*a)-&gt;name, (*b)-&gt;name);
      strcpy((*b)-&gt;name, nameTemp);
  }
  
  /*
   * Calculates the difference between first and second
   */
  void calculateDiff() {
      Node *curr = front;
      while(curr != NULL) {
          curr-&gt;dif = abs((curr-&gt;first - curr-&gt;second));
          curr = curr-&gt;next;
      }
  }
  
  /*
   * Prints all the data from the nodes.
   */
  void printAll() {
      printf("|| Word || RedBadge || LittleRegiment ||  Diff\n");
      Node *curr = front;
      while ( curr != NULL  ) {
          printf("%s, %d, %d, %d\n", curr-&gt;name, curr-&gt;first, curr-&gt;second, curr-&gt;dif);
          curr = curr-&gt;next;
      }
  }
  
  /*
   * main.c
   */
  #include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;string.h&gt;
  #include &lt;ctype.h&gt;
  #include "list.h"
  
  void readBook(int book, FILE *infile);
  void readLine(char *line, int book);
  
  int main (void) {
      setvbuf(stdout, NULL, _IONBF,0);
      FILE *infile = fopen("RedBadge.txt", "r");
      FILE *infile2 = fopen("LittleRegiment.txt", "r");
      readBook(1, infile);
      readBook(2, infile2);
      fclose(infile);
      fclose(infile2);
      calculateDiff(); 
      sort();
      printAll();
      return 0;
  }
  
  void readBook(int book, FILE *infile) {
      char line[70];
  
      //Read in each line
      while (!feof(infile)) {
          fgets(line, 70, infile);
          readLine(line, book);
      }
  }
  
  void readLine(char *line, int book) {
      int i = 0, j = 0;
      char word[20];
  
  
      while (line[i]) {
          line[i] = tolower(line[i]); //Convert line to lowercase
          if((line[i] &lt;= 'z' &amp;&amp; line[i] &gt;= 'a') || line[i] == 39 || line[i] == '-') {
              word[j] = line[i];
              j++;
          } else if (j != 0) {
              word[j] = '\0';
              findWord(word, book);
              j = 0;
          }
          i++;
      }
  }
  </code></pre>