Solved

fstream variable issue

Posted on 2011-03-14
12
326 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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 34

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 34

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 34

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 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 34

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

Industry Leaders: 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!

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Lambda for random numbers problem 7 120
C++ standard library based binary archive format 6 108
C++ to C# code conversion issue 4 117
Finding Divisors 5 35
When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
In days of old, returning something by value from a function in C++ was necessarily avoided because it would, invariably, involve one or even two copies of the object being created and potentially costly calls to a copy-constructor and destructor. A…
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 technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

740 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