开发者

first fstream program

I am trying to write a program that gets data from this text file:

first fstream program

Then, based on this data, the program is supposed to calculate the average gpa of each gender (f=female, m=male) and output the results in a new file.

It must also contain these five functions:

openFiles: this function opens the input and output files and sets the output of floating-point numbers to two decimal places in a fixed decimal format with a decimal point and trailing zeros.

initialize: this function initializes variables.

sumGrades: This function finds the sum of the female and male students GPAs.

average grade: This function finds the average GPA for male and female students.

printResults: this function outputs the relevent results.

I think I've done pretty good coding up the functions and all but since this is my first program using fstream im not sure how i need to implement them in my main function.

Here is what i have so far:

header:

#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&, floa开发者_Python百科t&);
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

main:

#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;
}

openFiles:

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

averageGrade:

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

printResults:

#include "header.h"

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


You're making good progress.

You don't need the static_casts in averageGrade.

printResults is missing most of its function signature.

In sumGrades, gpa and gender should be local variables, not parameters. You also want to compare to the character literals 'm' and 'f', not variables named m and f with random contents.

Streams should ALWAYS be passed by reference, they can't be copied.

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

Did you have a question?


You must pass the file streams by non-const references:

void extern openFiles(ifstream&, ofstream&);

sumGrades and printResults don't care that these streams are files, so you can pass just streams, still these must be references:

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

averageGrade is missing extern.

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

openFiles does nothing useful. It opens files and closes them... You shouldn't close them:

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

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

The point is that you should call these function to open the files from 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.
// ...


Don;t do this:

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

If it fails to read gender or gpa it still does stuff.
Wchich means that that the last line of your file was processed twice.

A better way to write this is:

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

Now STUFF is only done if gender and gpa are correctly read from the file.

This if statement is not required.

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

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

You can use a map (or other container to hold these values). That way your code is more readable (and when we get a new third species easier to expand).

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.

Looks like this:

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


printResults must not have copied correctly. I suspect it must have the signature

void printResults(float maleGrade, float femaleGrad);

When you are reading your file you need to see if the gender is m or f then branch and add the next GPA to the gender GPA.

something like

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜