0

I want to read in numbers from text file and create a linked list dynamically, although I am able to do it, the last node with value of 0 is also added to the list. How can I correct this? Also I should be able to add value 0 if i want but not in this way.

    #include <stdio.h>
    #include <stdlib.h>

    typedef struct node {
      int data;
      struct node *next;
    }node;


    int main(int argc, char const *argv[]) {

      FILE *fp = fopen("data.txt", "r");

      node *prev = NULL;
      while(!feof(fp)){
        node *curr = malloc(sizeof(node));

        fscanf(fp, "%d", &(curr->data));           
        fprintf(stdout, "%d-->", curr->data);

        if(prev != NULL){
          prev->next = curr;
        }
        prev = curr;
      }
      printf("NULL\n");

      fclose(fp);
      return 0;
    }

The input file is this single column of integers 1 5 2 3 6 4

The output comes like this, the 0 is not part of input 1-->5-->2-->3-->6-->4-->0-->NULL

inSynergy
  • 77
  • 3
  • 12
  • You will want to see [**Why is “while ( !feof (file) )” always wrong?**](http://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong?s=1|2.6948) – David C. Rankin Jul 15 '16 at 23:20

1 Answers1

2

Following on from the comment, your use of while (!feof(fp)) is wrong. If you are using fscanf, you should check the return (e.g. == 1) to determine success or failure of conversion. You should also read the value into a temporary value (rather than your list data) so you can validate the number before assigning it to your list.

Putting that together, you could do something like the following (note: the code reads values from the filename passed as the 1st argument (or from stdin) if no argument is given)

#include <stdio.h>
#include <stdlib.h>

typedef struct node {
    int data;
    struct node *next;
} node;


int main (int argc, char **argv) {

    int tmp = 0;
    node *prev = NULL;
    FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
    if (!fp) {  /* validate file is open for reading */
        fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
        return 1;
    }

    while (fscanf (fp, " %d", &tmp) == 1) {  /* validate conversion to tmp */

        node *curr = malloc (sizeof (node));

        curr->data = tmp;                    /* assign tmp to curr->data */
        fprintf (stdout, "%d-->", curr->data);

        if (prev != NULL) {
            prev->next = curr;
        }
        prev = curr;
    }
    putchar ('\n');

    if (fp != stdin) fclose (fp);  /* close if not reading from stdin */

    return 0;
}

Additionally, when you simply need a '\n', don't use printf, there is no need. Simply use putchar ('\n');

Look it over and let me know if you have questions.

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85