Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

fstream variable issue

Posted on 2011-03-14
12
Medium Priority
?
331 Views
Last Modified: 2012-06-27
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
Comment
Question by:pgmerLA
  • 4
  • 4
  • 4
12 Comments
 
LVL 53

Expert Comment

by:Infinity08
ID: 35130621
>> 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
 
LVL 35

Expert Comment

by:sarabande
ID: 35130708
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
 

Author Comment

by:pgmerLA
ID: 35130936
Hi Infinity08, could you write me a sample code?

Thanks.
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:pgmerLA
ID: 35130951
Hi Sara,

how would I know it's the end of the file?
Can I use that for a very very long file?
0
 
LVL 35

Assisted Solution

by:sarabande
sarabande earned 1000 total points
ID: 35131159
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
 
LVL 35

Expert Comment

by:sarabande
ID: 35131187
yes you could use it for long textfiles as well. but you probably will do somewhat with the x numbers.

Sara
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 35131257
>> 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
 

Author Comment

by:pgmerLA
ID: 35131413
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
 
LVL 53

Accepted Solution

by:
Infinity08 earned 1000 total points
ID: 35131758
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
 

Author Comment

by:pgmerLA
ID: 35131783
Thanks a lot guys!
0
 
LVL 35

Expert Comment

by:sarabande
ID: 35135575
instead of

    if (f.eof()) break;

i would suggest

   if (!f) break;

that would cover both eof and fail condition.

Sara
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 35135726
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

New feature and membership benefit!

New feature! Upgrade and increase expert visibility of your issues with Priority Questions.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

885 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question