Thread: eof in fstream & singly linked lists

  1. #1
    Registered User
    Join Date
    Jun 2002
    Posts
    29

    eof in fstream & singly linked lists

    I want to know more about singly linked lists, so I decided to write a program: it would read some integers from a file, store them in linked list (*root) and sort them (and store sorted list in *sorted). This program is working, but I think it's not very readable and also I have found some problems:

    In while loop (!fin.eof()) equals 1, when the input file is emty. It equals 0 only after reading from empty file, so my program creates one more node than is required, and I have to destroy it (using variable badnode and code around it..)
    How I can read data (and store them in linked list) better, without problems with eof?

    Also the sorting part isn't enough readable because of a great amount of if-else statements, and I think I don't need them.. I will think about it and I'll try to rewrite it
    Do you know about some good tutorial about linked lists, binary trees and such things(for example 'halda', I don't know how it is called in English, maybe 'heap'..) ?

    Code:
    #include <iostream.h>
    #include <fstream.h>
    #include <process.h>
    
    struct NodeT {
      int value;
      NodeT *next;
    };
    
    void printlist(NodeT *root)
    {
      cout << ": ";
      while (root != NULL) {
    	cout << root->value << ' ';
    	root = root->next;
      }
      cout << endl;
    }
    
    int main(void)
    {
      /**** reading data: ****/
    
      ifstream fin("x.x");
    
      NodeT *root, *sorted, *p, *badnode;
      p = root = sorted = NULL; badnode = NULL;
    
      while (!fin.eof()) {
    	if (root == NULL) { // zaciatok
    	  p = root = new NodeT;
    	}
    	else {
    	  badnode = p;
    	  p->next = new NodeT;
    	  p = p->next;
    	}
    	fin >> p->value;
    	p->next = NULL;
      }
    
      if (badnode == NULL) {
    	delete root;
    	root = NULL;
      }
      else {
    	delete badnode->next;
    	badnode->next = NULL;
      }
      p = NULL;
    
      // **** sort: ****
    
      NodeT *lastsortednode, *min;
    
      while (root != NULL) {
    	cout << "root "; printlist(root);
    	cout << "sorted "; printlist(sorted);
    	min = p = root;
    
    	while (p != NULL) {
    	  if (p->value < min->value)
    		min = p;
    	  p = p->next;
    	} // najde minimum min->value
    
    	if (min == root) {
    	  if (sorted == NULL) {
    		lastsortednode = sorted = root;
    	  }
    	  else {
    		lastsortednode->next = root; // adds node with minimal value to sorted list
    		lastsortednode = lastsortednode->next;
    	  }
    	  root = root->next;
    	  lastsortednode->next = NULL;
    	}
    	else {
    	  p = root;
    	  while (p != NULL) {
    		if (p->next == min)
    		  break;
    		p = p->next;
    	  } // finds node before minimum (p->next = min)
    
    	  if (sorted == NULL) {
    		lastsortednode = sorted = p->next;
    	  }
    	  else {
    		lastsortednode->next = p->next; // adds node with minimal value to sorted list
    		lastsortednode = lastsortednode->next;
    	  }
    	  p->next = min->next; // throws min out of unsorted part of list
    	  lastsortednode->next = NULL;
    	} // else (min == root)
      } // while root
      cout << "root "; printlist(root);
      cout << "sorted "; printlist(sorted);
    
      fin.close();
    
      system("pause");
      return 0;
    }

  2. #2
    Unregistered
    Guest
    be sure there is no newline at the end of the last file line and before the EOF marker. If there is, then fin >> p->value; will stop at the new line right before the EOF marker, but it is not yet at the EOF marker. Therefore the loop will do one more read in before it reaches the EOF marker and stop input. The last input is garbage and can be anything, but in my experience is frequently a duplicate of the last p->value read in.

    Another way to deal with this is to do a priming read before starting the while loop (ideally you have a mechanism to handle an empty file either way), or use some other terminating condition for the while loop.

  3. #3
    Registered User
    Join Date
    Jun 2002
    Posts
    29
    The input file was totally empty, but the fstream::eof() isn't working in way I want it to do.. these ideas are good, but is there no way to not use a priming read? Some other condition maybe, I don't want to use C functions and C style, because I want C++ program
    if you have some idea about the condition in while loop, post it here.. thanks..

  4. #4
    Unregistered
    Guest
    try this:

    //declare a new node to receive input outside the loop
    //then read in first value
    fin >> p->value;

    //this conditional means as long as the ifstream is valid
    while(fin)
    {
    //continue

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Need help with FIFO Queue using Singly Linked Lists
    By astou in forum C++ Programming
    Replies: 6
    Last Post: 03-15-2008, 02:36 PM
  2. Singly Linked Lists: Clarification Needed
    By jedispy in forum C++ Programming
    Replies: 4
    Last Post: 12-14-2006, 05:30 PM
  3. Linked Lists 101
    By The Brain in forum C++ Programming
    Replies: 5
    Last Post: 07-24-2004, 04:32 PM
  4. need help w/ linked lists
    By MKashlev in forum C++ Programming
    Replies: 11
    Last Post: 08-05-2002, 08:57 PM
  5. Re: Singly Linked Lists
    By Linette in forum C++ Programming
    Replies: 2
    Last Post: 01-23-2002, 12:10 PM