Solved

fstream variable issue

Posted on 2011-03-14
12
322 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 32

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
 

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 32

Assisted Solution

by:sarabande
sarabande earned 250 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 32

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
Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

 
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 250 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 32

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

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

IntroductionThis article is the second in a three part article series on the Visual Studio 2008 Debugger.  It provides tips in setting and using breakpoints. If not familiar with this debugger, you can find a basic introduction in the EE article loc…
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

744 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

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now