c ++读取文本文件和输出等级并平均到另一个文件(混乱的输出)

时间:2012-01-15 09:50:00

标签: c++ file text

  

可能重复:
  enhancing a program - complete failure

我要求编写一个程序,以下列形式阅读文本文件的内容:

Jones Tom 94 99 96 74 56 33 65 89 87 85  
Thompson Frank 67 58 86 95 47 86 79 64 76 45  
Jackson Tom 95 97 94 87 67 84 99 45 99 87  
Jackson Michael 43 23 34 77 64 35 89 56 75 85  
Johnson Sara 84 93 64 57 89 99 74 64 75 35 91

并以下列形式将每个学生的平均值输出到另一个文件中:

Jones Tom 94 99 96 74 56 33 65 89 87 85 77.8
Thompson Frank 67 58 86 95 47 86 79 64 76 45 70.3
Jackson Tom 95 97 94 87 67 84 99 45 99 87 85.4
Jackson Michael 43 23 34 77 64 35 89 56 75 85 58.1
Johnson Sara 84 93 64 57 89 99 74 64 75 35 73.4

我成功地使用以下代码完成了这项工作:

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

    int main()
    {
        fstream infile("grades.txt",ios::in);
        if(!infile){cerr<<"file could not be found!";exit(1);}

        fstream outfile("average.txt",ios::out);
        if(!outfile){cerr<<"file could not be created!";exit(1);}


        char fname[20];
        char lname[20];
        int grades;
        char c;
        int lines=1;
        double avg=0;

        while(infile.get(c))
        {if(c=='\n') lines++;}
        infile.clear();
        infile.seekg(0);

        for(int k=0;k<lines;k++)
            {
                infile>>fname;
                infile>>lname;
                outfile<<fname<<" "<<lname<<" ";
                int sum=0;
                for(int i=0;i<10;i++)
                {
                    if(infile>>grades)
                    {sum+=grades;
                    outfile<<grades<<" ";}
                }

                outfile<<(double)sum/10.0<<endl;
            }


        system("pause");
        return 0;
    }

但我有一个问题。 当文本文件的第一行包含小于10的等级时,例如:

  

Jones Tom 94 99 96 74 56 33 65 89 87

我得到了混乱的输出,这破坏了一切。我得到以下输出:

Jones Tom 94 99 96 74 56 33 65 89 87 69.3
  0
  0
  0
  0

我该如何解决这个问题?如果我在每一行上的成绩不到十个,我如何让程序输出零? 所以,例如,如果我在第一行:

Jones Tom 94 99 96 74 56 33 65 89

我希望程序计算平均值并将以下内容输出到另一个文件。

Jones Tom 94 99 96 74 56 33 65 89 0 0 64.3

请注意,64.3是学生的平均值。

谢谢你。 亲切的问候。

2 个答案:

答案 0 :(得分:1)

嗯,解决方案非常简单。首先,将代码分为两部分,第一部分读取成绩,进行平均并将成绩写入输出文件,第二部分写入零和平均值。

读取分数的部分会在sum中累积它们。现在,您可以使用总和和计数器来计算平均值。

让我们看一下读取分数的代码是如何工作的

//Repeat till all grades are read and then move on to the next student
num_grades_read = 0;
while //grades are available on the line
{
    //Read in a new grade
    sum += grades;
    //Write the read grade to the output file.
    outfile << grades;
    num_grades_read++;
}

最后,在写入输出文件的第二部分中,您将要执行以下操作:

int limit = 10 - num_grades_read;
for(int j = 0; j < num_grades_read; ++j)
{
    //Write zero to the file
    outfile << 0 << " ";
}
//Write the computed average to the file
outfile << (double)(sum) / num_grades_read << endl;

现在,上面的伪代码不是很好,因为它没有检查等。例如,您需要确保您没有读过10多个等级。

由于您在第一部分中遇到了问题,这里有一些代码可以提供帮助:

while(!infile.fail())
{
    infile >> grade;
    sum += grade;
    outfile<<grade<<" ";
    num_grades_read++;
}
infile.clear();

我希望这会有所帮助。

答案 1 :(得分:1)

用于计算每行平均值的算法不正确,并且无需拨打clear()seekg(),您希望逐步浏览文件。

此外,无需对等级数进行硬编码。您可以计算这些!

我建议您使用std::getline()一次读取整行,并std::istringstream读取每个年级。这是从纯文本文件中读取数字的惯用方法,与一次读取一个字符的工作相比要少得多!

由于这看起来像是家庭作业,或者至少是练习,我不会提供真正的代码......

while (std::getline(infile, line))
{
    std::istringstream iss(line);
    // Reset values for the number of grades and the total score here

    if (iss >> fname >> lname) // Ensure that we've read in these values...
    {
        // Output the name and then iterate over the scores...
        while (iss >> grade)
        {
            // Recalculate the total based on the new grade
            // Increment the number of grades
            // Output the current grade
        }

        // End of the line
        // Mean = total / number of grades
        // Output mean
    }
}