Dec 10, 2015 at 7:16am UTC
Hi, so I've got a HW and am little stuck.
The gold is "Write a program that reads students’ names followed by their test scores from an input file. The program should output to a file, output.txt, each student’s name followed by their test score and the relevant grade."
Here's my code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
using namespace std;
struct StudentType
{
string studentFName;
string studentLName;
int testScore;
char grade;
};
int loadData(StudentType students[], int nStudents);
void outputData(StudentType students[], int nStudents);
char letGrades(int grade);
void calGrades(StudentType students[], int nStudents);
int main()
{
int studentCount = 0;
StudentType students[20];
calGrades(students, studentCount);
studentCount = loadData(students, studentCount );
if (studentCount >= 20)
{
cout << "Sorry, you can't put any more students." << endl;
studentCount++;
}
system("pause" );
return 0;
}
void calGrades(StudentType students[], const int nStudents)
{
int i;
for (i = 0; i < nStudents; i++)
{
students[i].grade = letGrades(students[i].testScore);
}
}
char letGrades(int grade)
{
char charGrades;
if (grade >= 90)
{
charGrades = 'A' ;
}
else if (grade >= 80)
{
charGrades = 'B' ;
}
else if (grade >= 70)
{
charGrades = 'C' ;
}
else if (grade >= 60)
{
charGrades = 'D' ;
}
else
{
charGrades = 'F' ;
}
return charGrades;
}
int loadData(StudentType students[], int nStudents)
{
int studentCount = 0;
ifstream input;
input.open("studentTest.txt" );
while (!input.eof())
{
input >> students[studentCount].studentFName;
input >> students[studentCount].studentLName;
input >> students[studentCount].testScore;
studentCount++;
}
input.close();
return studentCount;
}
void outputData(StudentType students[], int nStudents)
{
ofstream output;
output.open("studentTestScore.txt" );
for (int i = 0; i < nStudents; i++)
{
output << left << endl;
output << setw(5) << "Name: " << students[i].studentLName << ", " << students[i].studentFName << endl;
output << setw(5) << "Score: " << students[i].testScore << endl;
output << setw(5) << "Grade: " << students[i].grade << endl << endl;
}
output.close();
}
Why it doesn't create an output file? help!
Last edited on Dec 10, 2015 at 7:17am UTC
Dec 10, 2015 at 7:36am UTC
I don't think you ever called the outputData()
function. So the code never runs hence the file is never created.
also I believe that you didnt use the parameter nStudents
in loadData()
I'd assume the variable is to have the size of the class so that you can loop inputingData the number of times there are students,and loadData() should be a void function that doesnt need to return number of students.
Last edited on Dec 10, 2015 at 7:42am UTC
Dec 10, 2015 at 7:58am UTC
So I've changed loadData as a void function and called the outputData function.
but this time it doesn't output anything.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
using namespace std;
struct StudentType
{
string studentFName;
string studentLName;
int testScore;
char grade;
};
void loadData(StudentType students[], int nStudents);
void outputData(StudentType students[], int nStudents);
char letGrades(int grade);
void calGrades(StudentType students[], int nStudents);
int main()
{
ifstream input;
ofstream output;
int studentCount = 0;
StudentType students[20];
calGrades(students, studentCount);
if (studentCount >= 20)
{
cout << "Sorry, you can't put any more students." << endl;
studentCount++;
}
outputData(students, studentCount);
system("pause" );
return 0;
}
void calGrades(StudentType students[], const int nStudents)
{
int i;
for (i = 0; i < nStudents; i++)
{
students[i].grade = letGrades(students[i].testScore);
}
}
char letGrades(int grade)
{
char charGrades;
if (grade >= 90)
{
charGrades = 'A' ;
}
else if (grade >= 80)
{
charGrades = 'B' ;
}
else if (grade >= 70)
{
charGrades = 'C' ;
}
else if (grade >= 60)
{
charGrades = 'D' ;
}
else
{
charGrades = 'F' ;
}
return charGrades;
}
void loadData(StudentType students[], int nStudents)
{
int studentCount = 0;
ifstream input;
input.open("studentTest.txt" );
while (!input.eof())
{
input >> students[studentCount].studentFName;
input >> students[studentCount].studentLName;
input >> students[studentCount].testScore;
studentCount++;
}
input.close();
}
void outputData(StudentType students[], int nStudents)
{
ofstream output;
output.open("studentTestScore.txt" );
for (int i = 0; i < nStudents; i++)
{
output << left << endl;
output << setw(5) << "Name: " << students[i].studentLName << ", " << students[i].studentFName << endl;
output << setw(5) << "Score: " << students[i].testScore << endl;
output << setw(5) << "Grade: " << students[i].grade << endl << endl;
}
output.close();
}
Last edited on Dec 10, 2015 at 8:14am UTC
Dec 10, 2015 at 10:51am UTC
To be fair, it doesn't input anything either, because function
loadData()
is never called.
I'd start with calling that from main(), and then check how many students were read.
1 2 3 4 5 6 7 8 9 10 11 12 13 14
void loadData(StudentType students[], int & nStudents);
const int MAXSIZE = 20;
int main()
{
int studentCount = 0;
StudentType students[MAXSIZE];
loadData(students, studentCount);
cout << "Number of students: " << studentCount << '\n' ;
return 0;
}
Note the
& here
int & nStudents
, it means the parameter is passed by reference so its value may be modified inside the function.
Inside function
loadData()
there are a number of changes needed.
1. use the parameter
nStudents
instead of a separate variable
2. don't loop on
eof()
, it is unreliable and can lead to unexpected errors.
3. take care that MAXSIZE is not exceeded
4. check that the file access was successful before adding 1 to the count
nStudents
For both 2 and 4 simply test the condition (input), for example
if (input)
or
while (input)
see:
http://www.cplusplus.com/reference/ios/ios/operator_bool/
Last edited on Dec 10, 2015 at 10:54am UTC
Dec 10, 2015 at 11:03pm UTC
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
using namespace std;
struct StudentType
{
string studentFName;
string studentLName;
int testScore;
char grade;
};
const int MAXSIZE = 20;
void loadData(StudentType students[], int & nStudents);
void outputData(StudentType students[], int nStudents);
char letGrades(int grade);
void calGrades(StudentType students[], int nStudents);
int main()
{
ifstream input;
ofstream output;
int studentCount = 0;
StudentType students[MAXSIZE];
loadData(students, studentCount);
calGrades(students, studentCount);
cout << "Number of students: " << studentCount << '\n' ;
if (studentCount >= MAXSIZE)
{
cout << "Sorry, you can't put any more students." << endl;
}
outputData(students, studentCount);
system("pause" );
return 0;
}
void calGrades(StudentType students[], const int nStudents)
{
int i;
for (i = 0; i < nStudents; i++)
{
students[i].grade = letGrades(students[i].testScore);
}
}
char letGrades(int grade)
{
char charGrades;
if (grade >= 90)
{
charGrades = 'A' ;
}
else if (grade >= 80)
{
charGrades = 'B' ;
}
else if (grade >= 70)
{
charGrades = 'C' ;
}
else if (grade >= 60)
{
charGrades = 'D' ;
}
else
{
charGrades = 'F' ;
}
return charGrades;
}
void loadData(StudentType students[], int & nStudents)
{
ifstream input;
input.open("studentTest.txt" );
while (!input.eof())
{
input >> students[nStudents].studentFName;
input >> students[nStudents].studentLName;
input >> students[nStudents].testScore;
}
input.close();
}
void outputData(StudentType students[], int nStudents)
{
ofstream output;
output.open("studentTestScore.txt" );
for (int i = 0; i < nStudents; i++)
{
output << left << endl;
output << setw(5) << "Name: " << students[i].studentLName << ", " << students[i].studentFName << endl;
output << setw(5) << "Score: " << students[i].testScore << endl;
output << setw(5) << "Grade: " << students[i].grade << endl << endl;
}
output.close();
}
Still outputs nothing..could u be more specific?
Last edited on Dec 10, 2015 at 11:03pm UTC
Dec 10, 2015 at 11:11pm UTC
In: loadData
You only read into a single element.
You do not increase the element count to indicate any thing has been read (which is why the subsequent function calls depending on studentCount to be accurate do nothing.)
Looping on eof like you're doing is wrong.