Hey.
My question is to read from a csv file and provide a user functionality to sort and output the data by grades, name and student id.. The code is compiling and running. The trouble I am getting now is outputting the file to different files when being sorted out by name, id, and grade. I have created separate options that asks the user how s/he wants to view the file. The first option works fine, however, the other two options do not work (ie. the output files arent created just like option 1). I would very much appreciate the help if someone could highlight what im doing wrong and what can i do to fix it. This will also help me better understand simple things.. Thanks in advance
#include <iostream>
#include <fstream>
#include <vector>
#include <sstream>
#include <string>
#include <cstdlib>
#include <stdio.h>
#include <algorithm>
using namespace std;
struct records
{
string name;
string id;
double mark;
string grade;
};
bool check_user_input (int num){
bool check_variable = true;
if (num <= 0 or num > 4)
check_variable = false;
return check_variable;
}
void print_message()
{
cout<<"This program determines the grades of students."<<endl;
}
void option_menu()
{
cout << "\n\nPlease choose an option to view grades according to your preferences." << endl;
cout << "Your options--ENTER-- " << endl;
cout << "\t- 1 - Order the grades by student name" << endl;
cout << "\t- 2 - Order the grades by student ID" << endl;
cout << "\t- 3 - Order the grades by grades" << endl;
cout << "\t- 4 - Exit" << endl;
cout << "\n\t*************************************\n\n" << endl;
}
void discard_line(ifstream &in)
{
char c;
do
in.get(c);
while (c!='\n');
}
bool sortByName(const records &lhs, const records &rhs)
{
return lhs.name < rhs.name;
}
bool sort_by_id(const records &lhs, const records &rhs)
{
return lhs.id < rhs.id;
}
bool sort_by_grade(const records &lhs, const records &rhs)
{
return lhs.grade < rhs.grade;
}
string determine_grade(double sfinal_marks)
{
string sgrade;
if (sfinal_marks >= 85)
sgrade = "A+";
else if(sfinal_marks >= 78)
sgrade = "A";
else if(sfinal_marks >= 71)
sgrade = "B+";
else if(sfinal_marks >= 64)
sgrade = "B";
else if(sfinal_marks >= 57)
sgrade = "C+";
else if(sfinal_marks >= 50)
sgrade = "C";
else if(sfinal_marks >= 40)
sgrade = "D";
else
sgrade = "E";
return sgrade;
}
int main()
{
int option;
print_message();
option_menu();
ifstream infile;
ofstream osGradesByName;
ofstream osGradesByID;
ofstream osGrades;
vector <records> sub;
records rec;
int i=0; //keeps track of total records read from file
string str;
infile.open("input.csv",ios::in);
if (infile.fail()){
cerr<<"File not found!";
exit(EXIT_FAILURE);
}
discard_line(infile);
while ((getline(infile, str))){ // Read a whole line (until it reads a '\n', by default)
string line_value;
int index = str.find_first_of(',');
string tname = str.substr(0,index);
rec.name=tname ;
line_value = str.substr(index+1);
int index2 = line_value.find_first_of(',');
string tid = line_value.substr(0,index2);
rec.id=tid;
string tmark = line_value.substr(index2+1);
rec.mark=atof(tmark.c_str());
rec.grade = determine_grade(rec.mark);
sub.push_back(rec);
i++;
}
infile.close();
cout << "Name: \t\t\t\t" << "id: \t\t\t" << "marks: \t\t\t" << "Grade: " << endl;
for(int j=0; j<3; j++){
cout << "--------------------------------------------------------------------------------------------------------" << endl;
cout<<sub[j].name << "\t\t\t" << sub[j].id << "\t\t\t" << sub[j].mark<<"\t\t\t" << sub[j].grade << endl;// <<" \t " <<sub[j].mark<<endl;
}
for (int j=4; j < 5; j++)
{
cout << "--------------------------------------------------------------------------------------------------------" << endl;
cout<<sub[j].name << "\t\t" << sub[j].id << "\t\t\t" << sub[j].mark<<"\t\t\t" << sub[j].grade << endl;
}
for (int j=5; j < 6; j++)
{
cout << "--------------------------------------------------------------------------------------------------------" << endl;
cout<<sub[j].name << "\t\t\t" << sub[j].id << "\t\t\t" << sub[j].mark<<"\t\t\t" << sub[j].grade << endl;
}
for (int j = 6; j < 7; j++)
{
cout << "--------------------------------------------------------------------------------------------------------" << endl;
cout<<sub[j].name << "\t\t" << sub[j].id << "\t\t\t" << sub[j].mark<<"\t\t\t" << sub[j].grade << endl;
}
cout<< "\n\nEnter option: ";
cin >> option;
while(check_user_input(option) == false)
{
std::cout << "\nIncorrect Option: ";
std::cout << "\nPlease Enter OPTION Again: ";
std::cin >> option;
}
if (option = 1)
{
//ofstream osGradesByName;
osGradesByName.open("GradesByName.txt", ios::out);
osGradesByName << "After sorting by name\n" << endl;
sort(sub.begin(), sub.end(), sortByName);
for(records &n : sub)
{
osGradesByName << n.name << "\t\t\t" << n.id << "\t\t\t" << n.mark << "\t\t\t" <<n.grade << endl;
}
osGradesByName.close();
}
else if (option = 2) //THIS IS WHERE I START HAVING TROUBLES!!
{
//ofstream osGradesByID;
osGradesByID.open("GradesByID.txt", ios::out);
osGradesByID << "After sorting by Student\n" <<endl;
sort(sub.begin(), sub.end(), sort_by_id);
for (records &n : sub)
{
osGradesByID << n.id << "\t\t\t" << n.name << "\t\t\t" << n.mark << "\t\t\t" << n.grade << endl;
}
osGradesByID.close();
}
else if(option = 3)
{
//ofstream osGrades;
osGrades.open("Grades.txt", ios::out);
osGrades << "After sorting by Students Grades\n" << endl;
sort(sub.begin(), sub.end(), sort_by_grade);
for (records &n : sub)
{
osGrades<< n.grade << "\t\t\t" << n.mark << "\t\t\t" << n.name << "\t\t\t" << n.id << endl;
}
osGrades.close();
}
return 0;
}