• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 332
  • Last Modified:

fstream variable issue

Hi,
Do you know why the last value on my file is being printed twice?

Thanks for your help. data.txt
#include<iostream>
#include<fstream>

using namespace std;

int main(){
	ifstream f;
	f.open("data.txt");
	int x=0;
	while(!f.eof())
	{f>>x;
	cout<<x<<' ';
	cout<<endl;
	}


return 0;
}

Open in new window

0
pgmerLA
Asked:
pgmerLA
  • 4
  • 4
  • 4
2 Solutions
 
Infinity08Commented:
>> Do you know why the last value on my file is being printed twice?

Because the end of the file is not reached until after trying to read past it.

The last line is read from the file, but it doesn't set the eof flag yet, so the code tries to read another entry, and that fails, so the eof flag is set, but you don't check the eof flag before printing out the data.

Either check eof before the cout (and end the loop if it's set), or use a line based approach by using getline to read the file one line at a time :

        http://www.cplusplus.com/reference/string/getline/
0
 
sarabandeCommented:
you could simply code like

   if (f>>x)
      cout<<x<<endl;

note the additional space makes not so much sense if you do a new line after.

Sara
0
 
pgmerLAAuthor Commented:
Hi Infinity08, could you write me a sample code?

Thanks.
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
pgmerLAAuthor Commented:
Hi Sara,

how would I know it's the end of the file?
Can I use that for a very very long file?
0
 
sarabandeCommented:
the f>>x would fail on eof. the problem is it also will fail if it reads not an integer.

to make it really safe you should apply infinity08's advice and read with getline. after that use istringstream to retrieve the integers:

      
ifstream f("data.txt");
	int x=0;
                     std::string s;
	while(getline(f, s))
	{
                            std::istringstream is(s); // seed with textline
                            while (is>>x)
	            cout<<x<<endl;
	}

Open in new window


the above would read the whole textfile line by line. if a line contains alphabetics all numbers after were ignored, but the outer while loop doesn't stop, if not using stringstream the first non-integer would make the f stream fail and no further operation nor the check on f.eof() would succeed after. that means the loop goes infinite.

Sara
0
 
sarabandeCommented:
yes you could use it for long textfiles as well. but you probably will do somewhat with the x numbers.

Sara
0
 
Infinity08Commented:
>> Hi Infinity08, could you write me a sample code?

What would you like a sample code for ?

Do you understand what the issue is in your original code ? If not, please let me know which part of my explanation requires clarification, and I'll be happy to provide it.
0
 
pgmerLAAuthor Commented:
I understand the issue.
Could you write me an example for : "Either check eof before the cout (and end the loop if it's set)"
Would I use a do..while loop in that case?
0
 
Infinity08Commented:
You need to check if the eof flag was set after reading the data, but before trying to use the data. However you want to do that, works.

But what I was alluding to, was :

        while(!f.eof())
        {
            f>>x;
            if (f.eof()) break;
            cout<<x<<' ';
            cout<<endl;
        }

However, that still doesn't take care of all possible error cases, so I still recommend using getline to read the file line by line in a loop.
0
 
pgmerLAAuthor Commented:
Thanks a lot guys!
0
 
sarabandeCommented:
instead of

    if (f.eof()) break;

i would suggest

   if (!f) break;

that would cover both eof and fail condition.

Sara
0
 
Infinity08Commented:
That line was specifically meant to get rid of the "last value on my file is being printed twice" problem. It was not a recommendation to actually use that in production code. My recommendation for production code, is to use a line-based approach using getline (see my previous posts).
0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

  • 4
  • 4
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now