Asked  7 Months ago    Answers:  5   Viewed   227 times

The following C++ code uses a ifstream object to read integers from a text file (which has one number per line) until it hits EOF. Why does it read the integer on the last line twice? How to fix this?

Code:

#include <iostream>
#include <fstream>
using namespace std;

int main()
{
    ifstream iFile("input.txt");    // input.txt has integers, one per line

    while (!iFile.eof())
    {
        int x;
        iFile >> x;
        cerr << x << endl;
    }

    return 0;
}

input.txt:

10  
20  
30

Output:

10  
20  
30  
30

Note: I've skipped all error checking code to keep the code snippet small. The above behaviour is seen on Windows (Visual C++), cygwin (gcc) and Linux (gcc).

 Answers

74

Just follow closely the chain of events.

  • Grab 10
  • Grab 20
  • Grab 30
  • Grab EOF

Look at the second-to-last iteration. You grabbed 30, then carried on to check for EOF. You haven't reached EOF because the EOF mark hasn't been read yet ("binarically" speaking, its conceptual location is just after the 30 line). Therefore you carry on to the next iteration. x is still 30 from previous iteration. Now you read from the stream and you get EOF. x remains 30 and the ios::eofbit is raised. You output to stderr x (which is 30, just like in the previous iteration). Next you check for EOF in the loop condition, and this time you're out of the loop.

Try this:

while (true) {
    int x;
    iFile >> x;
    if( iFile.eof() ) break;
    cerr << x << endl;
}

By the way, there is another bug in your code. Did you ever try to run it on an empty file? The behaviour you get is for the exact same reason.

Tuesday, June 1, 2021
 
daiscog
answered 7 Months ago
21

You can open the file using the ios::ate flag (and ios::binary flag), so the tellg() function will give you directly the file size:

ifstream file( "example.txt", ios::binary | ios::ate);
return file.tellg();
Wednesday, June 9, 2021
 
Magnanimity
answered 6 Months ago
38

In short:

iostream.h is deprecated—it is the original Stroustrup version. iostream is the version from the standards committee. Generally, compilers point them both to the same thing, but some older compilers won't have the older one. In some odd cases, they will both exist and be different (to support legacy code) and you then must be specific.

"" versus <> simply means check the local directories for the header before going to the library (in most compilers).

Friday, June 11, 2021
 
macha
answered 6 Months ago
37

You could actually use xlsread to accomplish this. After first placing your sample data above in a file 'input_file.csv', here is an example for how you can get the numeric values, text values, and the raw data in the file from the three outputs from xlsread:

>> [numData,textData,rawData] = xlsread('input_file.csv')

numData =     % An array of the numeric values from the file

   51.9358    4.1833
   51.9354    4.1841
   51.9352    4.1846
   51.9343    4.1864
   51.9343    4.1864
   51.9341    4.1869


textData =    % A cell array of strings for the text values from the file

    'ABC'
    'ABC'
    'ABC'
    'ABC'
    'ABC'
    'ABC'


rawData =     % All the data from the file (numeric and text) in a cell array

    'ABC'    [51.9358]    [4.1833]
    'ABC'    [51.9354]    [4.1841]
    'ABC'    [51.9352]    [4.1846]
    'ABC'    [51.9343]    [4.1864]
    'ABC'    [51.9343]    [4.1864]
    'ABC'    [51.9341]    [4.1869]

You can then perform whatever processing you need to on the numeric data, then resave a subset of the rows of data to a new file using xlswrite. Here's an example:

index = sqrt(sum(numData.^2,2)) >= 50;  % Find the rows where the point is
                                        %   at a distance of 50 or greater
                                        %   from the origin
xlswrite('output_file.csv',rawData(index,:));  % Write those rows to a new file
Friday, July 23, 2021
 
LukeP
answered 5 Months ago
66

You'll have to:
save your position
close the file
reopen the file
seek to your saved postion and resume reading until EOF

Saturday, August 21, 2021
 
Anand S Kumar
answered 4 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share