我正在尝试编写一个从该文本文件中获取数据的程序:
然后,根据这些数据,程序应该计算每个性别的平均gpa(f =女性,m =男性),并将结果输出到新文件中。
它还必须包含以下五个功能:
openFiles :此函数打开输入和输出文件,并将浮点数的输出设置为带小数点和尾随零的固定十进制格式的两位小数。
初始化:此函数初始化变量。
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;
}
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;
}
答案 0 :(得分:3)
你取得了很好的进展。
您不需要static_cast
中的averageGrade
。
printResults
缺少大部分功能签名。
在sumGrades
中,gpa
和gender
应该是局部变量,而不是参数。您还希望与字符文字'm'
和'f'
进行比较,而不是与随机内容名称为m
和f
的变量进行比较。
Streams应始终通过引用传递,不能复制。
When reading from a stream, you should test the stream itself in your while loop, not eof()
.
你有问题吗?
答案 1 :(得分:2)
您必须通过非const引用传递文件流:
void extern openFiles(ifstream&, ofstream&);
sumGrades
和printResults
并不关心这些流是文件,因此您只能传递流,但这些必须是引用:
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.
// ...
答案 2 :(得分:0)
不要这样做:
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).
}
答案 3 :(得分:-1)
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