13 Replies - 26048 Views - Last Post: 02 March 2010 - 07:39 PM Rate Topic: -----

#1 k2283944  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 31
  • Joined: 04-November 08

eof while loop

Posted 17 January 2009 - 10:53 AM

I'm reading in a file with a name, age, height, and weight with a while loop. Whenever I run my program, it repeats the last line of the file. I know what the problem is, im just not sure how to fix it. I need to prime my while loop to stop it to repeating the last line. I think im just having a mental block or something.

Heres my code for my loop:
while( ! infile.eof()){

infile >> name >> age >> height >> weight;

cout << left << setw(15) << name << right << setw(8) << age << setw(8) << height
		<< showpoint << fixed << setprecision(2) << setw(10) << weight;
cout << endl;
}



Is This A Good Question/Topic? 0
  • +

Replies To: eof while loop

#2 Martyr2  Icon User is offline

  • Programming Theoretician
  • member icon

Reputation: 4364
  • View blog
  • Posts: 12,182
  • Joined: 18-April 07

Re: eof while loop

Posted 17 January 2009 - 11:15 AM

The problem is that you have a space at the end of the last line or you hit return which is adding another line. Make sure there are no trailing spaces in your file text and that should solve the problem.

The reason the space is doing that is because it won't be the end of the file (you have this space left over) so it triggers another iteration of the loop where you attempt to pull in more data. Since you don't pull in more data (other than that space) it repeats all the values in the variables from the last line you read.

:)
Was This Post Helpful? 0
  • +
  • -

#3 k2283944  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 31
  • Joined: 04-November 08

Re: eof while loop

Posted 17 January 2009 - 11:27 AM

That would be a good fix, but its for a class and I'm sure i cant modify the input file.

Thanks
Was This Post Helpful? 0
  • +
  • -

#4 dan_ram  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 4
  • View blog
  • Posts: 141
  • Joined: 15-August 07

Re: eof while loop

Posted 17 January 2009 - 11:45 AM

hm..why dont u try reading the
infile >> name >> age >> height >> weight;
before the loop the 1st time and then enter the loop?
Was This Post Helpful? 0
  • +
  • -

#5 k2283944  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 31
  • Joined: 04-November 08

Re: eof while loop

Posted 17 January 2009 - 11:47 AM

Just tried that, and it still had the same output except for my first line of input was missing

output before:

Little 35 76 325.00
Smith 25 74 265.50
Jackson 14 60 155.75
Pebody 62 54 500.25
Small 80 96 1000.13
Big 2 2 4.01
Big 2 2 4.01

output after adding infile >> name >> age >> height >> weight; before loop:

Smith 25 74 265.50
Jackson 14 60 155.75
Pebody 62 54 500.25
Small 80 96 1000.13
Big 2 2 4.01
Big 2 2 4.01

I know the numbers aren't lined up on here, but they line up fine in my output file

This post has been edited by k2283944: 17 January 2009 - 11:53 AM

Was This Post Helpful? 0
  • +
  • -

#6 dan_ram  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 4
  • View blog
  • Posts: 141
  • Joined: 15-August 07

Re: eof while loop

Posted 17 January 2009 - 11:59 AM

i meant:
infile >> name >> age >> height >> weight;
while( ! infile.eof()){
	cout << left << setw(15) << name << right << setw(8) << age <<		 setw(8)  << height
		<< showpoint << fixed << setprecision(2) << setw(10) << weight;
cout << endl;
infile >> name >> age >> height >> weight;
}


guess you tried
infile >> name >> age >> height >> weight;

while( ! infile.eof()){

infile >> name >> age >> height >> weight;

cout << left << setw(15) << name << right << setw(8) << age << setw(8) << height
		<< showpoint << fixed << setprecision(2) << setw(10) << weight;
cout << endl;
}


Was This Post Helpful? 0
  • +
  • -

#7 k2283944  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 31
  • Joined: 04-November 08

Re: eof while loop

Posted 17 January 2009 - 12:04 PM

That done it. Thanks I appreciate it a lot.
Was This Post Helpful? 0
  • +
  • -

#8 dan_ram  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 4
  • View blog
  • Posts: 141
  • Joined: 15-August 07

Re: eof while loop

Posted 17 January 2009 - 12:12 PM

welcome!! nice to see that you replied! :D
Was This Post Helpful? 0
  • +
  • -

#9 k2283944  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 31
  • Joined: 04-November 08

Re: eof while loop

Posted 17 January 2009 - 12:13 PM

Got to give credit where credit is due!

This post has been edited by k2283944: 17 January 2009 - 12:13 PM

Was This Post Helpful? 0
  • +
  • -

#10 Bench  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 857
  • View blog
  • Posts: 2,341
  • Joined: 20-August 07

Re: eof while loop

Posted 17 January 2009 - 02:01 PM

the 'while not eof' construct is wrong for C++. EOF is a flag which is set in a stream after a failure occurs.
In other words, when you read the last line of a file, everything is OK. When you subsequently attempt to read 'past the end', the EOF flag is set. At which point its too late, because your check for EOF will have happened before you'd tried reading any data.

in C++ you should use constructs such as
while ( myfile >> obj )
or
while ( std::getline(myfile, mystring) )
in order to avoid these kinds of problems

If a read operation fails, your loop will see the fail condition immediately

This post has been edited by Bench: 17 January 2009 - 02:02 PM

Was This Post Helpful? 1
  • +
  • -

#11 David W  Icon User is offline

  • DIC supporter
  • member icon

Reputation: 281
  • View blog
  • Posts: 1,788
  • Joined: 20-September 08

Re: eof while loop

Posted 18 January 2009 - 04:02 PM

View PostBench, on 17 Jan, 2009 - 01:01 PM, said:

the 'while not eof' construct is wrong for C++. EOF is a flag which is set in a stream after a failure occurs.
In other words, when you read the last line of a file, everything is OK. When you subsequently attempt to read 'past the end', the EOF flag is set. At which point its too late, because your check for EOF will have happened before you'd tried reading any data.

in C++ you should use constructs such as
while ( myfile >> obj )
or
while ( std::getline(myfile, mystring) )
in order to avoid these kinds of problems

If a read operation fails, your loop will see the fail condition immediately


Great stuff Bench ... If you have time ... what is your take on the problems with C EOF ? That seems to be some mysterious stuff ... ? (And ... many here might appreciate your comments?)

Shalom,
David
Was This Post Helpful? 0
  • +
  • -

#13 Bench  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 857
  • View blog
  • Posts: 2,341
  • Joined: 20-August 07

Re: eof while loop

Posted 19 January 2009 - 01:21 PM

David W - I'm not quite sure of the question? If its whether C has the same problem, then the answer is yes - since C and C++ both use the notion of "streams" for I/O. moreover, it can be solved using the same idiom of read while there is still data to be read

Here's the C equivalent using fgets instead of getline -
#define MAXLEN 1000

/* ... */
    char mystring[MAXLEN];
    while ( fgets(mystring, MAXLEN-1, myfile) )
/* ...  */ 
fgets in C is roughly equivalent to getline in C++ - although fgets returns a char*, which will either be NULL (if the read was unsuccessful) or it'll be a pointer to the first char of mystring.
it follows that fscanf is roughly equivalent to the stream retrieval >> operator, with the caveat that fscanf returns the number of arguments which it has successfully read from a stream; Whereas the >> operator returns a reference to the stream itself instead (which in-turn might be checked for failure in an if or while).
Checking a successful call to fscanf might look something like this
int num;
while (fscanf(myfile, "%d", &num) == 1) 



the EOF #define itself is just a constant, whose value signals an error or end of file if returned from a function using that stream (either its eof or error flags are currently set) - just as with C++ streams, a flag is set after a failed operation. eg,
int ch;
ch = fgetc(myfile);
if( ch == EOF )
    //etc.. 



On the subject of the cstdio/stdio.h, dinkumware's library reference is great for checking this sort of stuff http://www.dinkumwar...page=stdio.html
Was This Post Helpful? 1

#14 astropi  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 1
  • Joined: 02-March 10

Re: eof while loop

Posted 02 March 2010 - 03:19 PM

View PostBench, on 17 January 2009 - 01:01 PM, said:

the 'while not eof' construct is wrong for C++. EOF is a flag which is set in a stream after a failure occurs.
In other words, when you read the last line of a file, everything is OK. When you subsequently attempt to read 'past the end', the EOF flag is set. At which point its too late, because your check for EOF will have happened before you'd tried reading any data.

in C++ you should use constructs such as
while ( myfile >> obj )
or
while ( std::getline(myfile, mystring) )
in order to avoid these kinds of problems

If a read operation fails, your loop will see the fail condition immediately


OK, I have a question that's exactly along these lines! First, I will put in a disclaimer and note that none of this is homework related :) Now then, I did run into the EOF problem will writing a simple code (I'm new to C++):

int main(void)
{
  ifstream in;
  ofstream out;
  in.open("average.txt");
  double n_values;
  int counter = 0;
  double total = 0;
  double average;

  while (! in.eof())
  {
      in >> n_values;
      total = total + n;
      counter++;
      cout << n << endl;
    }
  average = total/counter;
  cout << "average " << average << endl;
}


So the above code should open a file, and give us the average. However because of the eof error it adds an extra line. I tried using Bench's advice, but have been unsuccessful. I'm honestly not sure how to go about implementing either of his lines into my code, so assistance would of course be greatly appreciated!

-astropi

This post has been edited by astropi: 02 March 2010 - 03:19 PM

Was This Post Helpful? 0
  • +
  • -

#15 David W  Icon User is offline

  • DIC supporter
  • member icon

Reputation: 281
  • View blog
  • Posts: 1,788
  • Joined: 20-September 08

Re: eof while loop

Posted 02 March 2010 - 07:39 PM

Bench's instructions are sound. (See the following working demo.)

#include <iostream>
#include <fstream>

using namespace std;

// average.txt
/*
1 2 3 4 5
6 7 8 9 10 11 12

*/

int main()
{
    ifstream fin( "average.txt" );
    double n_val, sum = 0, average;
    int counter = 0;
    while( fin >> n_val )
    {
        sum += n_val;
        ++counter;
        cout << "File value " << counter << " is "
             << n_val << " and the sum now is " << sum << endl;
    }
    average = sum/counter;
    cout << "And the average is " << average

         << "\n\nPress 'Enter' to continue ... " << flush;
    cin.get();
}

// output ...
/*
File value 1 is 1 and the sum now is 1
File value 2 is 2 and the sum now is 3
File value 3 is 3 and the sum now is 6
File value 4 is 4 and the sum now is 10
File value 5 is 5 and the sum now is 15
File value 6 is 6 and the sum now is 21
File value 7 is 7 and the sum now is 28
File value 8 is 8 and the sum now is 36
File value 9 is 9 and the sum now is 45
File value 10 is 10 and the sum now is 55
File value 11 is 11 and the sum now is 66
File value 12 is 12 and the sum now is 78
And the average is 6.5

Press 'Enter' to continue ...
*/


Was This Post Helpful? 0
  • +
  • -

Page 1 of 1