0

hello there. i needed a little help in writing coding for reading multiple lines of data from a .txt file that are seperated by commas.

Student Name, Student ID, Mark
Ada Lovelace , S001 , 99
Barbara Liskov , S0123 , 44
Carol Shaw, S0023 , 55
Donna Dubinsky , S8333 , 33
Shafi Goldwasser , S934 , 77
Sophie Wilson , S11813 , 22
Frances Elizabeth Allen , S8254 , 66

After reading the data, the data has to be graded and sorted by name, id and grade.
i would very much appreciate your guys help in this

2
Contributors
7
Replies
43
Views
1 Month
Discussion Span
Last Post by rproffitt
0

Hey.

I have worked on the above mentioned question and so far it is working nicely. 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 outfile;

    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(1);
    }

    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)
    {       

        outfile.open("Grades_Name.txt", ios::out | ios::ate);
        outfile << "After sorting by name\n" << endl;

        sort(sub.begin(), sub.end(), sortByName);
        for(records &n : sub)
        {
            outfile << n.name << "\t\t\t" << n.id << "\t\t\t" << n.mark << "\t\t\t" <<n.grade << endl;
        }   

    outfile.close();
    }

    else if (option = 2) //THIS IS WHERE I START HAVING TROUBLES!!
    {
        outfile.open("Grades_ID.txt", ios::out | ios::ate);
        outfile << "After sorting by Student Id\n" <<endl;

        sort(sub.begin(), sub.end(), sort_by_id);
        for (records &n : sub)
        {
            outfile << n.id << "\t\t\t" << n.name << "\t\t\t" << n.mark << "\t\t\t" << n.grade << endl;
        }

    outfile.close();
    }

    else if(option = 3)
    {
        outfile.open("Grades.txt", ios::out | ios::ate);
        outfile << "After sorting by Students Grades\n" << endl;

        sort(sub.begin(), sub.end(), sort_by_grade);
        for (records &n : sub)
        {
            outfile<< n.grade << "\t\t\t" << n.mark << "\t\t\t" << n.name << "\t\t\t" << n.id << endl;
        }
    outfile.close();
    }

    else

    return 0;
}
0

So why is line 179 assigning 1 to option? Same for other lines.

As to all the else if's, uncalled for. No need for else if. Just if's.

0

Thank you for highlighting my mistakes .. Much appreciated ..and thank you for the help. The program works as expected now

0

To avoid assignment errors like that, and this can be debated, read https://en.wikipedia.org/wiki/Yoda_conditions

For me the style is easy to read and in fact some compilers (citation needed) or code analyzers now check for probably assignment errors in code.

Now depending on your class or company, your coding style might be dictated. Folk I know accept both Yoda and non-Yoda conditions.

This question has already been answered. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.