Thread: sequential access file

  1. #1
    Registered User
    Join Date
    Jan 2002
    Posts
    8

    sequential access file

    ok, heres the problem, whenever i run this function it displays the proper results from the file, but the prints out a empty set of record fields i know its running through the while loop one extra time, but i dont know how to stop it! anyone have any suggestions??
    Code:
    void Displayallcustomers()
    {
    	string LASTNAME, FIRSTNAME, STREETADDRESS,           CITY, PROV, POSTALCODE;
    	ifstream infile;
    	infile.open("customers.dat", ios::in);
                    
                    if (infile.is_open())
                   {
    	while (!infile.eof())
    	{
                     getline(infile, LASTNAME, '#');
    	 getline(infile, FIRSTNAME, '#');
    	 getline(infile, STREETADDRESS, '#');
    	 getline(infile, CITY, '#');
    	 getline(infile, PROV, '#');
    	 getline(infile, POSTALCODE, '#');
    				
                     cout <<"Last Name:" << LASTNAME << "" <<endl; 
    	 cout <<"First Name:" << FIRSTNAME << "" <<endl; 
    	 cout <<"Street Address:" << STREETADDRESS     << ""<<endl; 
    	 cout <<"City:" << CITY << "" <<endl;
    	 cout <<"Province:" << PROV << "" <<endl; 
    	 cout <<"Postal Code:" << POSTALCODE << ""<<endl;
    
    	}
    	infile.close();
    			
                    }
    	else
    	cout<<"YOU HAVE SELECTED AN INVALID   OPTION"<<endl;
    }
    Tagged by Salem

  2. #2
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    You could start off by using code tags so I can read you code. THen you could change your while into a do while.

  3. #3
    Registered User
    Join Date
    Mar 2002
    Posts
    1,595
    I think it has to do with how streams work. It is my understanding that every time you call a method from a class derived from the ios class (ifstream is derived from istream wchich is derived from ios) it sets one or more bits in the stream "state". The "state" of the stream can then be evaluated by using other methods. In this case, the eof() method is called to evaluate the state of the stream to see if the last input resulted inputting EOF. If it did then eof() returns a non-zero value, otherwise it returns 0.

    The problem you are running into is that eof() checks the state of the stream but isn't a call for input per se.

    Let's use an example to try to clarify this. Say the file has two ints in it like this:

    1
    2

    and you want to read the file like this--mimicking what you do:

    while(!infile.eof())
    {
    infile >> num;
    cout << num;
    }

    What happens is that when the condition for while is checked before the first input is done, the EOF hasn't been found yet, so calling eof() returns 0, and !0 is evaluated to true. The program then reads in the first int and prints it to the screen. The first call to >> didn't result in finding EOF so when the conditional of while is checked again eof() still returns 0 and !0 is still true so the second int is read in and printed to the screen. So far so good. But now pay attention because here is the crux of the problem. The program has read in the last int from the file, but EOF still hasn't been found, so when the conditional of the while is checked again eof() still returns 0 and !0 is still true so there is a third passage through the body of the while loop, but there's nothing for infile to read in! You happen to get blanks as infile tries to read something in, other times you may get a double entry of the last piece of data, or some other wierd stuff, it's hard to say. The point is that EOF hasn't been found which means eof() still is going to return 0 which means !0 is true and you've got a problem.

    Now check this out. Same file, same code, with slight modification.

    infile >> num;
    while(!infile.eof())
    {
    cout << num;
    infile >> num;
    }

    Now the first call to infile occurs before the while loop. It doesn't result in reading in EOF so !eof() returns true and the value of num is printed to the screen. This time the call to infile in the loop comes after the call to cout << rather than before. And this is the crucial move, infile is called just before the call to while() a second time, and it works. Now at the end of the second run through the while loop infile >> num is called a third time. This time it does find EOF and the condition of the while turns positive and the loop stops without running a third time resulting in reading in just two values of num like you intended it to.

    IMO this is the proper way to do it. The other "fixes" already posted, do/while instead of while and while(getline()) will probably work okay as long as the file isn't empty to begin with, but they are likely to lead to problems if the file is empty to begin with, whereas this method won't. (I'll leave it up to you to work this out.)

    Therefore my suggestion to fix your code is as follows:

    Code:
    if (infile.is_open())
    {
      getline(infile, LASTNAME, '#')
      while (!infile.eof())
      {
         getline(infile, FIRSTNAME, '#');
         getline(infile, STREETADDRESS, '#');
         getline(infile, CITY, '#');
         getline(infile, PROV, '#');
         getline(infile, POSTALCODE, '#');
    				
          cout <<"Last Name:" << LASTNAME << "" <<endl; 
          cout <<"First Name:" << FIRSTNAME << "" <<endl; 
          cout <<"Street Address:" << STREETADDRESS          
                  << ""<<endl; 
          cout <<"City:" << CITY << "" <<endl;
          cout <<"Province:" << PROV << "" <<endl; 
          cout <<"Postal Code:" << POSTALCODE << ""<<endl;
    
          getline(infile, LASTNAME, '#');
      }

    Sorry for such a long winded answer, but it's not an easy concept to write about.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. sequential file program
    By needhelpbad in forum C Programming
    Replies: 80
    Last Post: 06-08-2008, 01:04 PM
  2. Inventory records
    By jsbeckton in forum C Programming
    Replies: 23
    Last Post: 06-28-2007, 04:14 AM
  3. sequential file help plz
    By dutrachr in forum C Programming
    Replies: 4
    Last Post: 04-18-2006, 11:41 AM
  4. Game Pointer Trouble?
    By Drahcir in forum C Programming
    Replies: 8
    Last Post: 02-04-2006, 02:53 AM
  5. Encryption program
    By zeiffelz in forum C Programming
    Replies: 1
    Last Post: 06-15-2005, 03:39 AM