Not getting all lines from a text file when using getline() in C++

冷暖自知 提交于 2019-12-11 20:35:28

问题


I was given a homework assignment to generate a txt file containing a random number of lines, each with a random amount of integers, ranging between a minimum value and a maximum value. Lots of rand() fun.

In any case, that was the easy part. The second part of the problem is to read over the first file and create a second file that contains some statistics, such as: the sum of all integers in the file, their average, min and max values, and my main issue: the sum of all integers in each line.

I have written the following code:

#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <cstdlib>
#include <cmath>
using namespace std;

int main()
{
        string newLine;
        stringstream ss;
        int newInput = 0, oldInput = 0;
        int lineSum = 0;
        int lineCounter = 0;
        int allSum = 0;
        int intCounter = 0;
        double averageOfAll = 0;
        int minInt = 0;
        int maxInt = 0;

.... // generating the first file. No issues here.

ifstream readFile;
readFile.open("inputFile.txt");

ofstream statFile;
statFile.open("stat.txt");

if(readFile.is_open()) {
        while (getline(readFile, newLine)) {    //my problem should be somewhere
                                                //around here...  
                ss.str("");
                ss << newLine;
                while(!ss.eof()) {
                        oldInput = newInput;
                        ss >> newInput;

                        cout << newInput << endl;
                        lineSum += newInput;
                        allSum += newInput;
                        intCounter++;
                        minInt = min(oldInput, newInput);
                        maxInt = max(oldInput, newInput);
                }

                lineCounter++;
                statFile << "The sum of all integers in line " << lineCounter
                << " is: " << lineSum << endl;
                lineSum = 0;
        }

        readFile.close();

        averageOfAll = static_cast<double>(allSum)/intCounter;

        statFile << endl << endl << "The sum of all integers in the whole file: "
        << allSum;
        statFile << endl << "The average of value of the whole stream of numbers: "
        << averageOfAll;
        statFile << endl << "The minimum integer in the input file: "
        << minInt;
        statFile << endl << "The maximum integer in the input file: "
        << maxInt;
        statFile << endl << endl << "End of file\n";

} else
        cout << endl << "ERROR: Unable to open file.\n";

statFile.close();

return 0;
}

When running the program, it seems like my loops do iterate over all the lines in the file. However, they only collect the integers from the first line, and the rest remains 0.

I would post screenshots of my outputs, but I do not have enough rep :( can anyone help out?


It worked!

inputFile.txt ^

statFile.txt (my output) ^

And like P0W and James Kanze suggested, it was a flag issue and a misuse of my streamstring. I corrected my code as follows:

.
.
.
 while (getline(readFile, newLine)) {
                    stringstream ss(newLine);

                    while(ss >> newInput) {

                            lineSum += newInput;
                            allSum += newInput;
                            intCounter++;
                            minInt = min(minInt, newInput);
                            maxInt = max(maxInt, newInput);
                    }
.
.
.

Thank you all!


回答1:


There are several issues, but the main one is that you're trying to reuse ss (which should properly be an std::istringstream). It's possible to do so, but it's fairly difficult to get right, since streams hold a lot of state which needs reinitializing. (In this case, the stream memorizes that it has seen end of file, and doesn't do anything else until that has been reset.) Your loop should look like:

while ( getline( readFile, newLine ) ) {
    std::istringstream ss( newLine );
    //  ...
}

And once you've got the std::istringstream, you don't want to loop until eof (which may or may not be set after the last successful input); you want to loop until an input fails. (After the input fails, you may want to check eof: if it isn't set, the input failed because of a format error in the line; e.g. someone entered "abc" instead of an integer.)




回答2:


You can try following for your inner while loop

ss << newLine;

while( ss >> newInput ) 
{
  //.... Your logic,
 // might need little update

  oldInput = newInput;
}

ss.clear( ); // clear the flags !


来源:https://stackoverflow.com/questions/26134028/not-getting-all-lines-from-a-text-file-when-using-getline-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!