在C ++中使用getline()时,不会从文本文件获取所有行 [英] Not getting all lines from a text file when using getline() in C++

查看:165
本文介绍了在C ++中使用getline()时,不会从文本文件获取所有行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我得到一个作业分配,以生成一个txt文件,其中包含随机数行,每个都有随机数的整数,范围在最小值和最大值之间。很多rand()有趣。



在任何情况下,这是容易的部分。问题的第二部分是读取第一个文件,并创建包含一些统计信息的第二个文件,例如:文件中所有整数的总和,它们的平均值,最小值和最大值,以及我的主要问题:sum

 <$ c 



我已写入以下代码: #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;

.... //生成第一个文件。这里没有问题。

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

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

if(readFile.is_open()){
while(getline(readFile,newLine)){//我的问题应该在这里
//这里...
ss.str();
ss<<新队;
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<< 行中所有整数的和< lineCounter
<< 是:< lineSum < endl;
lineSum = 0;
}

readFile.close();

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

statFile<< endl<< endl<< 整个文件中所有整数的总和:
<< allSum;
statFile<< endl<< 整个数据流的价值的平均值:
< averageOfAll;
statFile<< endl<< 输入文件中的最小整数:
<< minInt;
statFile<< endl<< 输入文件中的最大整数:
<< maxInt;
statFile<< endl<< endl<< End of file\\\
;

} else
cout<< endl<< 错误:无法打开file.\\\
;

statFile.close();

return 0;
}

运行程序时,似乎我的循环遍历所有行在文件中。但是,他们只从第一行收集整数,其余的保持为0.



我会发布我的输出的截图,但我没有足够的代理
任何人都可以帮忙?






inputFile.txt ^





statFile .txt(我的输出)^



像P0W和James Kanze建议的,这是一个标志问题和一个滥用我的streamstring我更正了我的代码如下: / p>

 


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

while(ss>> newInput){

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



谢谢大家!

方案

有几个问题,但主要的是你试图
重用 ss (这应该是一个
std :: istringstream )。这是可能的,但它是相当
很难得到正确,因为流拥有很多状态,
需要重新初始化。 (在这种情况下,流记住
它已经看到文件结束,并且不做任何事情,直到
已被重置。)你的循环应该像:

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

std :: istringstream ,你不想
循环,直到 eof 在最后
成功输入后设置);您要循环,直到输入失败。
之后输入失败,您可能需要检查 eof :如果
未设置,输入失败,因为
行中的格式错误;例如有人输入abc而不是整数。)


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!

解决方案

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.)

这篇关于在C ++中使用getline()时,不会从文本文件获取所有行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆