【问题标题】:first fstream program第一个 fstream 程序
【发布时间】:2010-12-19 03:21:51
【问题描述】:

我正在尝试编写一个从该文本文件中获取数据的程序:

然后,根据这些数据,程序应该计算每个性别(f=female,m=male)的平均gpa,并将结果输出到一个新文件中。

它还必须包含这五个函数:

openFiles:此函数打开输入和输出文件,并将浮点数的输出设置为固定十进制格式的两位小数,带小数点和尾随零。

initialize:该函数初始化变量。

sumGrades:该函数求男女学生GPA之和。

平均成绩:此函数计算男女学生的平均 GPA。

printResults:此函数输出相关结果。

我认为我已经对函数进行了很好的编码,但由于这是我第一个使用 fstream 的程序,我不确定我需要如何在我的主函数中实现它们。

这是我目前所拥有的:

标题

#ifndef header_h
#define header_h

#include <iostream>
#include <iomanip>
#include <fstream>
#include <cstring>
#include <cstdlib>

using namespace std;

void extern initialize(int&, int&, float&, float&);
void extern openFiles(ifstream, ofstream);
void extern sumGrades(ifstream, ofstream, char, float, int&, int&, float&, float&);
void averageGrade (float&, float&, float, int, float, int);
void extern printResults (float, float, ofstream);



#endif

主要

#include "header.h"


int main()
{
    char gender;
    float gpa, sumFemaleGPA, sumMaleGPA;
    ifstream inData;
    ofstream outData;
    int countFemale, countMale;



    inData.open("./Ch7_Ex4Data.txt");
    outData.open("./Ch7_Ex4Dataout.txt");

    do
    inData >> gender >> gpa;
    while(!inData.eof());




    inData.close();
    outData.close();

    system("PAUSE");
    return EXIT_SUCCESS;
}

打开文件

#include "header.h"

void openFiles(ifstream inData, ofstream outData)
{

    inData.open("./Ch7_Ex4Data.txt");
    outData.open("./Ch7_Ex4Dataout.txt");

    outData << fixed << showpoint << setprecision(2); 

    inData.close();
    outData.close();

}    

sumGrades

#include "header.h"

void sumGrades(ifstream inData, ofstream outData, char gender, float gpa, int& countFemale, int& countMale, float& sumFemaleGPA, 
               float& sumMaleGPA)
{
     char m, f;

    do
    {

     inData >> gender >> gpa;

           if(gender == m)
              {
                         sumMaleGPA += gpa;
                         countMale++;   
              }         

     else if (gender == f)
              {
                      sumFemaleGPA += gpa;
                      countFemale++;
              }
    }
    while(!inData.eof());
}                  

平均成绩

#include "header.h"

void averageGrade (float& maleGrade, float& femaleGrade, float sumMaleGPA, int countMale, float sumFemaleGPA, int countFemale)
{
     maleGrade = sumMaleGPA / static_cast<float>(countMale);

     femaleGrade = sumFemaleGPA / static_cast<float>(countFemale);
}   

打印结果

#include "header.h"

void
{
     outData << "average male GPA: " << maleGrade << endl;
     outData << "average female GPA: " << femaleGrade << endl;    
}     

【问题讨论】:

  • 你有什么问题?您当前的代码在做什么?是否存在编译器错误,还是行为不端?这是作业吗?如果是这样,它应该被标记为这样。
  • averageGrade 不需要 static_cast。

标签: c++


【解决方案1】:

你的进步很好。

您不需要averageGrade 中的static_casts。

printResults 缺少大部分函数签名。

sumGradesgpagender 中应该是局部变量,而不是参数。您还想与字符文字 'm''f' 进行比较,而不是与名为 mf 的随机内容变量进行比较。

流应该总是通过引用传递,它们不能被复制。

When reading from a stream, you should test the stream itself in your while loop, not eof().

你有问题吗?

【讨论】:

  • 我会完成你,因为我有点懒得写我的答案:main() 中的循环总是对相同的变量进行赋值(并且什么都不做)
  • 函数已定义但从未使用过
  • @pastjean: main 只是一团糟,显然它应该调用其他函数。
【解决方案2】:

您必须通过非常量引用传递文件流:

void extern openFiles(ifstream&, ofstream&);

sumGradesprintResults 不关心这些流是文件,所以你可以只传递流,但这些必须是引用:

void extern sumGrades(istream&, ostream&, char, float, int&, int&, float&, float&);
void extern printResults (float, float, ostream&);

averageGrade 缺少 extern

void extern averageGrade (float&, float&, float, int, float, int);

openFiles 没有任何用处。它打开文件并关闭它们......你不应该关闭它们:

void openFiles(ifstream& inData, ofstream& outData) {
    inData.open("./Ch7_Ex4Data.txt");
    outData.open("./Ch7_Ex4Dataout.txt");

    outData << fixed << showpoint << setprecision(2); 
    // leave them open    
}

关键是你应该调用这些函数来打开来自main的文件:

// in main():
ifstream inData;
ofstream outData;

openFiles(inData, outData);
// call other functions to do the task.
// pass inData and outData as above, where stream arguments are expected.
// ...

【讨论】:

    【解决方案3】:

    不要这样做:

    do
    {
        inData >> gender >> gpa;
        STUFF
    } while(!inData.eof());
    

    如果它无法读取性别或 gpa,它仍然会做一些事情。
    Wchich 表示文件的最后一行被处理了两次。

    更好的写法是:

    while( inData >> gender >> gpa )
    {
         STUFF
    }
    

    现在只有在从文件中正确读取性别和 gpa 时才会执行 STUFF。

    此 if 语句不是必需的。

          if(gender == m)
              {
                         sumMaleGPA += gpa;
                         countMale++;   
              }         
    
     else if (gender == f)
              {
                      sumFemaleGPA += gpa;
                      countFemale++;
              }
    

    您可以使用地图(或其他容器来保存这些值)。这样你的代码就更易读了(当我们得到一个新的第三个物种时更容易扩展)。

    std::map<char, std::pair<double, int> >   data;
    
    std::pair<int,int>&  value = data[gender];
    value.first += gpa;    // First contains the total gpa for a gender
    value.second++;        // Second contains the count of a gender.
    

    看起来像这样:

    void readData(std::istream& in, std::map<char, std::pair<double,int> >& data)
    {
            char    gender;
            double  gpa;
            while(inData >> gender >> gpa)
            {
                data[gender].first  += gpa;
                data[gender].second ++;
            }
    }
    //
    // Notice that we pass streams by reference.
    // Also notice that it is a generic stream not a file stream.
    // This function does not need to know the output is going to a file
    // so you can now re-use it to print to another type of stream std::cout
    void writeData(std::ostream& out, std::map<char, std::pair<double,int> >& data)
    {
        for(std::map<char, std::pair<double,int> >::const_iterator loop = data.begin();
            loop != data.end();
            ++loop
           )
        {
            char                  gender = loop->first;
            std::pair<double,int> value  = loop->second;
    
            out << gender << ": " << value.first / value.second << "\n";
        }
    }
    
    int main()
    {
            std::map<char, std::pair<double,int> >  data;
    
            std::ifstream                           inData("./Ch7_Ex4Data.txt");
            readData(inData, data);
    
            std::ofstream                           outData("./Ch7_Ex4Dataout.txt");
            writeData(outData, data);
    
            // Don;t bother to close the files.
            // This happens automatically when the file goes out of scope.
            //
            // Genereally you use close() manually when you want to catch a problem that
            // is happening when you close the file. Since even if you did find a problem
            // there is nothing you can do with the problem don;t do it.
            //
            // Also note: potentially close() can throw an exception.
            // If you let the file close automatically with the destructor (it calls close
            // catches the exception and throws it away).
    }
    

    【讨论】:

      【解决方案4】:

      printResults 必须没有正确复制。我怀疑它必须有签名

      void printResults(float maleGrade, float femaleGrad);
      

      在阅读文件时,您需要查看性别是 m 还是 f,然后分支并将下一个 GPA 添加到性别 GPA。

      类似

      if(gender == "m"){
         maleGPA += gpa;
         maleCount++;
      }
      else{
         femaleGPA += gpa;
          femaleCount++;
      }
      // Call the next functions you copy pasted from your homework assignment
      

      【讨论】:

      • 与字符串文字比较不会有预期的效果。
      猜你喜欢
      • 1970-01-01
      • 2020-06-25
      • 1970-01-01
      • 2014-06-04
      • 1970-01-01
      • 1970-01-01
      • 2013-12-26
      • 1970-01-01
      • 2019-05-06
      相关资源
      最近更新 更多