【问题标题】:Not getting all lines from a text file when using getline() in C++在 C++ 中使用 getline() 时未从文本文件中获取所有行
【发布时间】:2014-10-01 04:17:12
【问题描述】:

我的作业是生成一个包含随机行数的 txt 文件,每行包含随机数量的整数,范围在最小值和最大值之间。很多 rand() 的乐趣。

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

我写了以下代码:

#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)) {    //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;
}

运行程序时,我的循环似乎会遍历文件中的所有行。但是,它们只收集第一行的整数,其余的仍然是 0。

我会发布我的输出截图,但我没有足够的代表 :( 有人可以帮忙吗?


成功了!

输入文件.txt ^

statFile.txt(我的输出)^

就像 P0W 和 James Kanze 建议的那样,这是一个标志问题,也是对我的流字符串的滥用。我更正了我的代码如下:

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

                    while(ss >> newInput) {

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

谢谢大家!

【问题讨论】:

  • 您可以将 c++ 添加到主题列表中。很多人可能不遵循更精确的标签(甚至不知道它们的存在)。
  • 刚刚做了,JGrice 提出了我接受的编辑建议:) 谢谢大家

标签: c++ fstream getline sstream


【解决方案1】:

有几个问题,但主要的一个是你正在尝试 重用ss(这应该是正确的 std::istringstream)。这样做是可能的,但这是公平的 很难做到正确,因为流包含很多状态 需要重新初始化。 (在这种情况下,流会记住 它已经看到文件结尾,并且在此之前不做任何其他事情 已重置。)您的循环应如下所示:

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

一旦你得到std::istringstream,你就不想 循环直到eof(可能会或可能不会在最后一个 成功输入);你想循环直到输入失败。 (输入失败后,你可能要检查eof:如果它 未设置,由于格式错误,输入失败 线;例如有人输入了"abc" 而不是整数。)

【讨论】:

    【解决方案2】:

    您可以尝试关注您的内部 while 循环

    ss << newLine;
    
    while( ss >> newInput ) 
    {
      //.... Your logic,
     // might need little update
    
      oldInput = newInput;
    }
    
    ss.clear( ); // clear the flags !
    

    【讨论】:

    • 哦,所以可能是标志问题?因为它没有为下一次迭代清除??
    • @GilDekel 这几乎可以肯定是一个标志问题,但是流的标志比你想象的要多得多,clear() 只会重置错误标志。除非您真的知道自己在做什么,并且遇到性能问题,否则不要尝试重用流;只需创建一个新的。
    猜你喜欢
    • 1970-01-01
    • 2016-07-15
    • 1970-01-01
    • 2015-01-21
    • 1970-01-01
    • 2014-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多