Thread: reading a file

  1. #1
    Registered User
    Join Date
    May 2009
    Posts
    4

    reading a file

    Hi All,

    I am having some difficulty reading an additional file - my code is reading the last data twice. I am still pretty new at C++ so I know I am making a simple mistake, but I cannot figure out what it is. I am still in a beginners C++ class and this is part of one of my assignments. Here is the data from the file I am reading (data1.txt):

    Smith,Tom
    90 100
    10 10 10 10 10 10 2 1 10 10 10 10

    Jones,Mary
    90 90
    1 2 3 4 5 6 7 8 9 10 10 10

    Hubred,Nicolle
    100 100
    10 10 10 10 10 10 10 10 10 10 10 10

    Ball,Lucille
    50 90
    10 10 2 7 10 1 1 10 10 10 10 10

    I am using structs and an array to store the information (name, midterm grade, final grade, 12 quiz/hw grades). Everything seems to be working fine except Ball,Lucille is printing to the screen twice, rather than once. I am using in_file.eof() to detect the end of the file, but that is not seeming to do the trick. Below is my code - any help you can give would be greatly appreciated!!

    Code:
    #include <iostream> 
    #include <fstream>
    #include <cstdlib>
    using namespace std;
    
    //structure for a students name, hq/quiz average, midterm and final 
    //exam grades
    struct A_STUDENT
    {
    	string name;
    	int midterm;
    	int final;
    	int hw_quiz;
    };
    
    int main()
    {
    	ifstream in_file;
    	A_STUDENT person;
    	A_STUDENT hw_quiz_grades[12];
    	int size = 12;
    
    	in_file.open("data1.txt");
    	if (in_file.fail())
    	{
    	  cout << "Opening input file \"data1.txt\" failed\n" << endl;
    	  exit(1);
    	}
    
    	while (!in_file.eof())
    	{
    	  for (int i = 0; i < size; i++)
    	  {
    	    hw_quiz_grades[i].hw_quiz = 0;
    	  }
    
    	  in_file >> person.name >> person.midterm >> person.final;
    	  for (int i = 0; i < size; i++)
    	  {
    	    in_file >> hw_quiz_grades[i].hw_quiz;
    	  }
    
    	  cout << person.name << " " << person.midterm << " " << person.final << " ";
    	  for (int i = 0; i < size; i++)
    	  {
    	    cout << hw_quiz_grades[i].hw_quiz << " ";
    	  }
    	  cout << endl;
    	}
    
    	in_file.close();
    	return 0;
    }

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    eof doesn't happen until you try to read a record that isn't there. Since you're already in the middle of the loop when that happens, you can't use eof to control your loop. You'll need to rejigger your loop so that a read happens at the very top as your loop control thing.

  3. #3
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    In this case, you might be able to break out of the loop once the first read op fails:
    Code:
    if ( !(in_file >> person.name >> person.midterm >> person.final) ) break;
    What I would do to make things cleaner is overload the stream insertion and extraction operators (<</>>) for the A_STUDENT struct and then use the read operation's return result in the while loop's conditional. The whole input/output loop then becomes much simpler looking:
    Code:
    std::istream& operator>>(std::istream& is, A_STUDENT& rhs)
    {
       // Your code here to read an A_STUDENT struct from file
    }
    
    std::ostream& operator<<(std::ostream& os, const A_STUDENT& rhs)
    {
        // Your code here to write A_STUDENT struct details
    }
    
    ...
    
    // The new i/o processing loop then reduces all the way down to this.
    A_STUDENT person;
    while( in >> person )
      cout << person;
    [edit]Your struct should have an array of quiz grades, not just a single one.[/edit]
    Last edited by hk_mp5kpdw; 05-21-2009 at 06:20 AM.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  4. #4
    Registered User
    Join Date
    May 2009
    Posts
    4
    Thanks hk_mp5kpdw - I used a break statement and that worked great. I also changed my struct to have an array of hw_quiz.

    The condensed data above looks great but I am in a beginners class and we have not learned that yet so unfortunately I have to stick with the long way!!

    Thanks again for your help.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. opening empty file causes access violation
    By trevordunstan in forum C Programming
    Replies: 10
    Last Post: 10-21-2008, 11:19 PM
  2. Formatting the contents of a text file
    By dagorsul in forum C++ Programming
    Replies: 2
    Last Post: 04-29-2008, 12:36 PM
  3. Replies: 3
    Last Post: 03-04-2005, 02:46 PM
  4. Possible circular definition with singleton objects
    By techrolla in forum C++ Programming
    Replies: 3
    Last Post: 12-26-2004, 10:46 AM
  5. System
    By drdroid in forum C++ Programming
    Replies: 3
    Last Post: 06-28-2002, 10:12 PM