Hello, i am currently working on a grade program that displays the student name, id #, and 2 grades. I have to read each of these categories off of an input file which should look like the following for at least 20 students.:

EX:
Jack Smith
450654333
95 89

The output should look like:
Student Name ID Eng101 Hist201
Jack Smith 450654333 95(A) 89(B)

Class Average: ---

The first problem I am having is reading the output from my teacher's desired input file (the spaces between the first and last name and grades were killing me). Therefore, I change the input file to this to try to make it easier, but might lose points for doing so:

Jack
Smith
45456650
95
89


The second problem is calculating the grades and class average, i do not understand how to do so from an input file.

Here is my code thus far:

#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>

using namespace std;
const int MAX_STDS = 20;
struct StudentGrade {
     string first;
     string last;
     int id;
     float eng101;
     float hist201;
};

void init_students(StudentGrade[]);
void read_data(StudentGrade[], int&);
void print_results(const StudentGrade[], int);
//void calc_grade (StudentGrade[]);
//int calc_avg (StudentGrade[]);

int main()
{

    StudentGrade studList[MAX_STDS];
    int std_num;

    init_students(studList);
    read_data(studList, std_num);
    print_results(studList, std_num);

    return 0;

}

void init_students(StudentGrade st[])
{
    for (int j = 0; j < MAX_STDS; j++)
    {
       st[j].first = "";
       st[j].last = "";
       st[j].id = 0;
       st[j].eng101 = 0.0;
       st[j].hist201 = 0.0;
    }
}

void read_data(StudentGrade st[], int& num)
{
    ifstream inFile;
    string fileName;
    int i = 0;
  
    cout << "Enter file name that contains data: ";
    cin >> fileName;

    inFile.open(fileName.data());

    while (!inFile)
    {
       cout << "File does not exist!" << endl;
       cout << "Enter file name: ";
       cin >> fileName;
       inFile.open(fileName.data());
    }

    for (int i = 0; i < MAX_STDS; i++)
    {
        inFile >> st[i].first >> st[i].last
        >> st[i].id >> st[i].eng101 
        >> st[i].hist201;
    }
 
    num = i;
}

/*void calc_grade(StudentGrade st[])
{
    char letter;

    for (int i = 0; i < MAX_STDS; i++)
    {
       if ((st[i].eng101 < 60) || (st[i].hist201 < 60))
         letter = 'F'; 
       else if ((st[i].eng101 < 70) || (st[i].hist201 < 70))
         letter = 'D';
       else if ((st[i].eng101 < 80) || (st[i].hist201 < 80))
         letter = 'C';
       else if ((st[i].eng101 < 90) || (st[i].hist201 < 90))
         letter = 'B';
       else
         letter = 'A';
    }

}
*/
/*int calc_avg (StudentGrade st[])
{
    int avg;
    int sum;
    int num;

    for (int i = 0; i < MAX_STDS; i++)
    {
       sum = st[i].eng101 + st[i].hist201;
    }
      num = i;

      avg = sum / num;

      return (avg);
}

*/
void print_results(const StudentGrade st[], int num)
{
    
    cout << "Student Name" << setw(15) << "Student ID" << setw(15)
    << "Eng101" << setw(10) << "Hist201" << endl;

    for (int i = 0; i < MAX_STDS; i++)
    {
    cout << st[i].first << ' ' << st[i].last 
    << setw(20) << st[i].id << setw(15) << st[i].eng101 << 
     setw(10) << st[i].hist201 << endl;
    }
}

Any suggestions?

Recommended Answers

All 5 Replies

To read the name part from one line, do this.

ifstream inFile;

getline(inFile, studentName);

Replace "studentName" with whatever your variable for that is called.
This will get the whole string line.

You have been around long enough, you should know how code tags work. I suggest you fix your tag while you still can.

MrJNV already covered your name read issue. The space in the grades line shouldn't be an issue. In fact, it's beneficial. All you have to do is read into 2 grade variables. The space takes care of breaking up the input stream for you, just keep reading right through it.

so i would include getline(inFile, studentName) in my for loop so it reads all names?

Yea. So in our struct, instead if string first and string last, put something like string name.

Then use the getline in the loop.

thanks, that worked better but i still have some problems.

1.) When reading the inFile using getline, the output only reads the first name, the other 19 names, ids, and scores print out as 0.
2.) When compiling with the getAvg function not canceled out, an error occurs reading "using obselete binding of i" on line 94.
3.) Line 122 has the error "Too few arguments to function getAvg(--)"

Here is my revised code:

#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>

using namespace std;
#include "prog5.h"
#include "prog5-2.h"

void init_students(StudentGrade[]);
void read_data(StudentGrade[], int&);
void print_results(const StudentGrade[], int);
char getGrade (float);
int getAvg (StudentGrade[], int);

int main()
{

    StudentGrade studList[MAX_STDS];
    int std_num;

    init_students(studList);
    read_data(studList, std_num);
    print_results(studList, std_num);

    return 0;

}

void init_students(StudentGrade st[])
{
    for (int j = 0; j < MAX_STDS; j++)
    {
        st[j].name = "";
        st[j].id = 0;
        st[j].eng101 = 0.0;
        st[j].hist201 = 0.0;
    }
}

void read_data(StudentGrade st[], int& num)
{
    ifstream inFile;
    string fileName;
    int i = 0;
  
    cout << "Enter file name that contains data: ";
    cin >> fileName;

    inFile.open(fileName.data());

    while (!inFile)
    {
        cout << "File does not exist!" << endl;
        cout << "Enter file name: ";
        cin >> fileName;
        inFile.open(fileName.data());
    }

    getline(inFile, st[i].name);
  
    while (inFile){
        inFile >> st[i].id
        >> st[i].eng101 
        >> st[i].hist201;
       
        i++;

        getline(inFile, st[i].name);
    }

}

char getGrade(float score)
{
    if (score >= 90)
        return 'A';
    else if (score >= 80)
        return 'B';
    else if (score >= 70)
        return 'C';
    else if (score >= 60)
        return 'D';
    else
        return 'F';

}

int getAvg (StudentGrade st[], int num)
{
    int sum;
    float avg;    

    for (int i = 0; i < MAX_STDS; i++)
    {
       sum = st[i].eng101 + st[i].hist201;
    }
      num = i;

      avg = sum / num;

      return (avg);
}


void print_results(const StudentGrade st[], int num)
{
    int classAvg;
    
    cout << "Student Name" << setw(15) << "Student ID" << setw(15)
    << "Eng101" << setw(10) << "Hist201" << endl;

    for (int i = 0; i < MAX_STDS; i++)
    {
         cout << st[i].name << setw(20) << st[i].id 
         << setw(12) << st[i].eng101 << "(" 
         << getGrade(st[i].eng101) << ")"
         << setw(8) << st[i].hist201 
         << "(" << getGrade(st[i].hist201) << ")" << endl;
    }

    classAvg = getAvg (num);
    cout << "Class Average: " << classAvg << endl;
}

Any help?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.