file i/o help

This is a discussion on file i/o help within the C++ Programming forums, part of the General Programming Boards category; I am reading data from a file which I store in a linked list. However, for some reason when reading ...

  1. #1
    Registered User
    Join Date
    Oct 2002
    Posts
    9

    file i/o help

    I am reading data from a file which I store in a linked list. However, for some reason when reading the list
    I get an extra "node".
    Here is my code.
    Code:
      // while not the end of the files keep reading
       while(!sin.eof()) {
    
         sin >> nextChar;
         temp->idNumber = nextChar;  
         
         sin >> nextChar;
         temp->LastName = nextChar;  
         
         sin >> nextChar;
         temp->FirstName = nextChar; 
     
         sin >> nextChar;
         temp->Major = nextChar;  
    
         sin >> nextChar;
         temp->Class = nextChar;  
        
         InsertTail(temp); // insert the node
      
         count++;
      }
    The file I read is 10 lines long. It seems that the
    last element in the file fills an extra node up. So count prints 11 instead of 10.
    I am sure the above code is the problem. Any
    help would be great thanks in advance.

  2. #2
    Registered User
    Join Date
    Aug 2002
    Location
    Hermosa Beach, CA
    Posts
    446
    You will probably have to get your hands dirty and use the debugger. If you havent used one maybe somebody can get you started. What is the OS, and what compiler are you using?
    The crows maintain that a single crow could destroy the heavens. Doubtless this is so. But it proves nothing against the heavens, for the heavens signify simply: the impossibility of crows.

  3. #3
    Registered User
    Join Date
    Apr 2002
    Posts
    362
    Sure.

    The EOF flag is not turned "on" until after the last character of the file is read, hence, your 'problem'. In short, your WHILE loop is going through one additional iteration accounting for 'count' going to 11 vice 10.

    Try
    Code:
     
    while ( sin )
    {
    
    }
    This will account for all of the "flags" rather than testing for just EOF, i.e. good, bad, fail, eof.

    -Skipper
    "When the only tool you own is a hammer, every problem begins to resemble a nail." Abraham Maslow

  4. #4
    Registered User
    Join Date
    Oct 2002
    Posts
    9
    I am using SunOS 5.8 with g++ 2.95.3. I have also tried to get it to work on a FreeBSD box. Would it help if I posted the full code (quite long) ?
    Thanks.

  5. #5
    Registered User
    Join Date
    Oct 2002
    Posts
    9
    I tried the while(sin) {} it still is doing it. I think it may be the file. The thing is, this is the one I have to use for the project. . Here is the full code

    Code:
    void LList::read(string &infile) {
    
    REDO: // in the case where the file does not exist
          // we will repeatly jump to this local to try again
    
     ifstream sin; // create an instream
     sin.open(infile.c_str(), ios::in); // open the file
     
     // if the file can not be opened exit
     if(sin.fail()) {
      // print the error
      cerr << endl << "*** ERROR: Can not open " << infile << 
                      " for reading." << endl;
      // call getName and correct the mistake
      getName(infile);
      goto REDO; // jump back up to open
     }
    
      string nextChar; // hold string from sin
    
    #ifdef g++good 
    //  NOTE: since the version of g++ is unpatched, nothrow can not be used.
    
      DATA *temp = new (nothrow) DATA;
      if(temp == NULL) {
        cerr << "Could not allocate memory. Consider closing some " <<
             "applications.\n";
        exit(1);
      }
    
    #else
     // create a new instance of the DATA class (a node)
     DATA *temp = new DATA; // alternative form 
    #endif
      
       // while not the end of the files keep reading
       while(sin) {
         // NOTE: All data is assumed to be valid from the file
         //       so no type checking is needed.
         sin >> nextChar;
         temp->idNumber = nextChar;  
         
         sin >> nextChar;
         temp->LastName = nextChar;  
         
         sin >> nextChar;
         temp->FirstName = nextChar; 
     
         sin >> nextChar;
         temp->Major = nextChar;  
    
         sin >> nextChar;
         temp->Class = nextChar;  
        
         InsertTail(temp); // insert the node at the end of the list
         count++; // add number to list
      }
    
      delete temp; // free temp
      sin.close(); // close the file
    
    } // end method read
    See anything wrong with that?

  6. #6
    Registered User
    Join Date
    Aug 2002
    Location
    Hermosa Beach, CA
    Posts
    446
    For starters, why don't you consider writing an overload for operator>>. I suspect that the stream is invalid after you check it but before you have read in a whole object. The half filled element would then be the 11th entry. Maybe your file has a blank line at the end...

    Code:
    // helper function
    void get(istream& s, std::string& str)
    {
        s>>str;
    
        // check for a failed stream in the middle of reading a
        // record: Maybe you can throw an exception or something
        // here that you can catch in some outer while loop
        if ( s.fail() ) // throw Some_Exception();
    }
    
    istream& operator>>(istream& s, DATA& d)
    {
         get(s,d.idNumber); 
         
         get(s,d.LastName);
    
         get(s, d.FirstName); 
    
         get(s, d.Major); 
    
         get(s, d.Class);
    
         return s;
    }
    
    int main()
    {
        // much code excluded...
        DATA* data = new DATA();
        try {
            while(sin) {
                 sin>> *data;
                 InsertTail(data);
                 count++;
            }
        }
        catch(...) {
              // catch your exception here
         }
        return 0;
    }

  7. #7
    Registered User
    Join Date
    Apr 2002
    Posts
    362
    One possibility.

    If your file was created as a char array rather than a pure 'string', there would be a trailing '\0' character, or characters. This, of course, would signify the end of the array, but would also account for an additional, if unwanted, character in your WHILE loop.

    I'm starting to "reach" here myself, but it's a thought that you may want to pursue.

    The logic is simple enough. You're reading more than you should be reading. The question is, "Why?"

    -Skipper
    "When the only tool you own is a hammer, every problem begins to resemble a nail." Abraham Maslow

  8. #8
    Registered User
    Join Date
    Oct 2002
    Posts
    9
    Thanks for all the help guys.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Data Structure Eror
    By prominababy in forum C Programming
    Replies: 3
    Last Post: 01-06-2009, 09:35 AM
  2. Game Pointer Trouble?
    By Drahcir in forum C Programming
    Replies: 8
    Last Post: 02-04-2006, 02:53 AM
  3. 2 questions surrounding an I/O file
    By Guti14 in forum C Programming
    Replies: 2
    Last Post: 08-31-2004, 12:21 AM
  4. File I/O problems!!! Help!!!
    By Unregistered in forum C Programming
    Replies: 4
    Last Post: 05-17-2002, 09:09 PM
  5. advice on file i/o
    By Unregistered in forum C Programming
    Replies: 1
    Last Post: 11-29-2001, 05:56 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21