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

Duplicate of same. Short answers.

  1. Forget those else ifs. Just use if or switch.
  2. Why did you assign 1 to your variable in line 182?

i have created options that the user has to select to see the data as they wish to see.. for example, if the user selects option 1, the data will be sorted according to the name and then output it to the respective files .

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.