Input file reading error [duplicate] - c++

This question already has answers here:
Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?
(5 answers)
Closed 9 years ago.
Hi i currently wrote a program but I'm having problems with reading the file. It seems to have read the last line twice, as a result, producing the same results twice.
I had put the getline() function to read the first line, in order to store the string for the variable G.
The rest, I had stored it in a vector of the class object.
basically the file is opened and it performs this loop
file.open("bodies1.txt");
getline(file, G1);
....
while(!file.eof)
{
file >> body;
bodies.push_back(body);
}
this is what the text file look like (this is just a sample. not the actual thing)
0.02932
Sun 32 42 53 2 2
Moon 49 32 4 2 1
Jupiter 32 53 2 3 2
I really was wondering why it read the last line twice. Any suggestions?

while(!file.eof())
{
file >> body;
bodies.push_back(body);
}
After reading the last object in to body, eof is the next character. Then
file >> body;
tries to read it and fails. So whatever was in body before is still there and will be pushed in to the vector.
instead you should read like
while(file >> body)
{
bodies.push_back(body);
}
This way your while stops as soon as you encounter eof() and you will not do an extra push in to the vector.

Related

Why is there a blank line? [duplicate]

This question already has answers here:
Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?
(5 answers)
Why is “while( !feof(file) )” always wrong?
(5 answers)
Closed 7 years ago.
I have the following C++ program:
ofstream output("scores.txt");
output<<"John"<<" "<<"T"<<" "<<"Smith"<<" "<<90<<endl;
output<<"Eric"<<" "<<"K"<<" "<<"Jones"<<" "<<103<<endl;
output.close();
ifstream input;
input.open("scores.txt");
string line;
while (!input.eof()) {
getline(input, line);
cout<<line<<endl;
}
input.close();
cout<<"Done";
The output is:
John T Smith 90
Eric K Jones 103
Done
Why is there a blank line between Eric K Jones 103 and Done?
Structure your loop like this:
while (getline(input, line)) {
cout<<line<<endl;
}
Your duplicate line is because the way your read loop is structured, once you read the last line the eof bit is not set yet because readline succeeded. Therefore, you iterate one more time, doing a readline that does set the eof bit, then you do cout<<line<<endl and that last endl is your extra blank line.

c++ program tries to read from stream after eof [duplicate]

This question already has answers here:
Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?
(5 answers)
Why is “while( !feof(file) )” always wrong?
(5 answers)
Closed 7 years ago.
I have a file containing only one character 1 (there is no newline symbol after it)
Reading the contents with this method:
int value;
ifstream in("somefile");
for (!in.eof())
{
in >> value;
cout << "input: " << value << " , eof" << in.eof() << "'\n";
}
gives me the following output:
input: 1 , eof: 0
input: 1 , eof: 1
The questions are:
1) Why EOF flag is not set after first reading try? I mean, if program successfully reads the number on the first try, it somehow knows that the string representatiion of it is over. To find it out it has to try read at least one byte after 1 character and there it should have hitted EOF. Why that doesn' happen?
2) That said, if I have a file with one value per line, I always do have a duplicate of last input. Does it mean that I always have to discard it in any way and that would be correct? Or for example add extra check for EOF after in >> value; and only if it succeeds, do any logic I want?
I know that I can work around with readline() or while(in >> value) methods but it's more a question of understanding what really happens there.
Thank you.

Read integer file and store EACH line in ONE separate array

I'm trying to read this file and store each row in one array. Can someone please tell me how to implement the code for this?
2
2 10 1 2 7
3 8 3 7 7 10 7
I have the code below and I can save every element of the text file into an array, but I need to have the lines saved into seperate arrays. How do I do this?
fstream myfile("myfile's_address", ios_base::in);
int a;
while (myfile >> a)
{
word[increment] = a;
increment++;
}
First, use ifstream instead of fstream with ios_base::in.
Next, use std::getline() to get one line as a string, create one vector for it (perhaps in a vector<vector<string>>), then parse it (perhaps using std::istringstream).

Extra output when adding trailing spaces and using eof [duplicate]

This question already has answers here:
Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?
(5 answers)
Closed 9 years ago.
I am compiling the following code under Microsoft Visual Studio 2013
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ifstream in("filename.txt");
int n;
while (!in.eof()) {
in >> n;
cout << n << endl;
}
return 0;
}
filename.txt contains:
4
 
note: the second line is empty line.
I am getting this output:
4
4
My question is: Why 4 is duplicated in the output when I add trailing spaces or empty lines to the end of the file? and why eof is not working properly in this case?
Using !eof(), !fail(), !bad(), or !good(), is invariably the wrong way to condition your input. The point is to perform the extraction first, and then check if succeeded. If you do the former, you'll almost always get the problems you are experiencing.
The first extraction into n obtained 4 from the stream. After it found the newline it stopped and you printed the value of n. When the second loop executed, the extractor cleared the leading whitespace from the stream (meaning the newline after 4), found the end of the stream and set eofbit. Since no characters were extracted, it also set failbit. When you attempted to print the value again, all you were seeing was the result of the previous input operation.
This isn't the right way to perform a read. You have to do it before checking the stream. This is how it is commonly done:
while (in >> n)
{
std::cout << n << std::endl;
}
After the read is performed, operator bool() will be invoked on the stream, which will access its stream state and determine if the extraction succeeded. If it did, only then will the loop body execute.
You aren't checking the state of the operation. Even if in >> n; sets a status of fail (so n was not set to a new value), you perform the next line. See http://www.cplusplus.com/doc/tutorial/files/ or http://www.cplusplus.com/reference/istream/istream/operator%3E%3E/ or similar. Your file has an empty line before the eof, so you run the code in the while loop twice.
Here's what happens during the above code execution:
1st loop iteration:
read 4 into n
output n (4)
2nd loop iteration:
read EOF
(here there is no test for EOF)
output n (4)
3rd loop iteration (doesn't happen, because EOF was read during the last read)
You should be testing the state of in in your loop condition:
while (in >> n)
{
// all is good, carry on
}

How can I read a line of numbers from a file into a list? [duplicate]

This question already has answers here:
Read integers from a text file with C++ ifstream
(2 answers)
Closed 10 years ago.
Let's say I have a .in file with the first line of data "3 59 98" and the second line of data "8 52 77 45".
I'm trying to read each line of integers into a list. I already understand how to make a list and put numbers in the list. What I am having trouble with is how to get the first line of numbers into a list object.
the following is an idea of what I have so far:
// in is a filestream object
int a
while (in >> a)
{
integer_list.push_back(a);
}
I know this doesn't work because it puts both lines of numbers into one list.
Any suggestions?
Use getline to read a whole line and then create std::istringstream from this line. Read from the std::istringstream the numbers in the list just as if you are reading from a file stream.
What you need to do is to create a list of integer lists, although in C++ you would prefer to use a vector.
std::vector< std::vector<int> > list_of_integer_lists;
then for each line you would add a new list or vector.
list_of_integer_lists.push_back( std::vector<int>() );
and for each line you add the numbers to the last list.
list_of_integer_lists.back().push_back( number );