0

The code is designed to output a student roster, and enable the sorting of the table by first name, last name, grade, among others.

My program compiles and I actually get credit for the first few problems, however it seems I am having trouble with my SortByFirstName and SortByLastName functions, or the way those functions interact with SortByGrade. (these functions are at the bottom of the code, everything else should work fine)

When attempting to sort by last name or by first, the output comes out nearly correct, that is, the list appears to be sorted properly but then two of the middle names are unsorted. The grade values are also improperly swapped (or not swapped at all?).

When just sorting by grade there appears to be no problem, so Im assuming the error lies in the SortByFirstName and SortByLastName functions.

#include <vector>
#include <string>
#include <locale>
#include <iomanip>
using namespace std;

void PrintWelcome();
void GetNumberOfStudents(int &numOfStudents);
void PrintMenu();
char GetUserSelection();
void PrintSummary(const vector<string> &students, const vector<double> &grades);
void AddStudent(vector<string> &students, vector<double> &grades);
void RemoveStudent(vector<string> &students, vector<double> &grades);
void SortByFirstName(vector<string> &students, vector<double> &grades);
void SortByLastName(vector<string> &students, vector<double> &grades);
void SortByGrade(vector<string> &students, vector<double> &grades);

int main() {
    const char QUIT = 'q';
    const char ADD = 'a';
    const char REMOVE = 'r';
    const char PRINT = 'p';
    const char MENU = 'm';
    
   const char SORTFULL = 'f';
   const char SORTLAST = 'l';
   const char SORTGRADE = 'g';
    

    string thankYou = "Thank you for entering your students information!\n";
    string notValid = "Not a valid selection.\n";
    char selection;

    int numOfStudents;

    vector<string> students;
    vector<double> grades;

    //Print the Welcome Message
    PrintWelcome();
    //Get Number of Students
    GetNumberOfStudents(numOfStudents);
    //Add the total number of students to the student and grades vectors
    for(int i = 0; i <numOfStudents; i++){
        AddStudent(students, grades);
    }
    //Print thank you message
    cout << thankYou;
    //Print the Roster Menu
    PrintMenu();
    //Get the users selection
    selection = GetUserSelection();

    while(selection != QUIT){
        if(selection == ADD){
            AddStudent(students, grades);
        }
        else if(selection == REMOVE){
            RemoveStudent(students, grades);
        }
        else if(selection == PRINT){
            PrintSummary(students, grades);
        }
        else if(selection == MENU){
            PrintMenu();
        }
            /*Provide Implementation for other menu options*/
         else if (selection == SORTFULL){
            SortByFirstName(students, grades);
         }
         else if (selection == SORTLAST){
            SortByLastName(students, grades);
         }
         else if (selection == SORTGRADE){
            SortByGrade(students, grades);
         }

        else{
            cout << notValid;
        }
        selection = GetUserSelection();
    }



}

void PrintWelcome(){
    string welcome = "Welcome to the student roster!\n";
    cout << welcome;
}

void GetNumberOfStudents(int &numOfStudents){
    string numOfStudentsQuestion = "How many students are in your class?:\n";
    cout << numOfStudentsQuestion;
    cin >> numOfStudents;
}

void PrintMenu(){
    string menu = "Please choose one of the following options:\n"
                  "a: add a student\n"
                  "r: remove a student\n"
                  "p: print the class summary\n"
                  "m: print menu\n"
                  "f: sort - first name\n"
                  "l: sort - last name\n"
                  "g: sort - grade\n"
                  "q: quit program\n";

    cout << menu;
}
char GetUserSelection(){
    string selectionString = "selection:\n";
    char selection;
    cout << selectionString;
    cin >> selection;
    return selection;
}
void PrintSummary(const vector<string> &students, const vector<double> &grades){
    string summaryHeading = "Class Summary\n"
                            "------------------------\n";
    string nameGradeHeading = "Name                Grade\n"
                              "---------           --------\n";
    string numOfStudentsString = "Number of Students:\n"
                                 "-------------------\n";
    string averageGradeString = "Average Grade:\n"
                                "--------------\n";
    double sum = 0.0;
    double average = 0.0;
    int numOfStudents = students.size();
    cout << endl;
    cout << summaryHeading << nameGradeHeading;
    for(unsigned int i = 0; i < students.size(); i++){
        sum += grades.at(i);
        cout << left << setw(20) << students.at(i) << setprecision(2) << fixed << grades.at(i) << endl;
    }
    cout << numOfStudentsString << numOfStudents << endl;
    cout << averageGradeString << setprecision(2) << fixed << sum/numOfStudents << endl;
    cout << endl;
}
void AddStudent(vector<string> &students, vector<double> &grades){
    string studentInfo = "Please enter student (First Last Grade) info:\n";
    string firstName, lastName;
    double grade;

    cout << studentInfo;
    cin >> firstName >> lastName >> grade;
    students.push_back(firstName + " " + lastName);
    grades.push_back(grade);
}
void RemoveStudent(vector<string> &students, vector<double> &grades){
    string removeStudent = "Please enter students first and last name";
    string firstName, lastName;

    cout << removeStudent;
    cin >> firstName >> lastName;
    string fullName = firstName + " " + lastName;
    for(unsigned int i = 0; i < students.size(); i++){
        if(students.at(i) == fullName) {
            students.erase(students.begin() + i);
            grades.erase(grades.begin() + i);
            cout << "Removing: " << fullName;
        }
    }
}
void SortByFirstName(vector<string> &students, vector<double> &grades){
string firstName1, firstName2;
string temp;
int pos;
double tempGrade;
   for(unsigned int i=0; i<students.size();i++){
      pos=students[i].find(' ');
      firstName1=students[i].substr(0,pos);
      for(unsigned int j=i+1;j<students.size();j++){
         pos=students[j].find(' ');
         firstName2=students[j].substr(0,pos);
         if(firstName1>firstName2){
            temp=students[i];
            students[i]=students[j];
            students[j]=temp;
            tempGrade=grades[i];
            grades[i]=grades[j];
            grades[j]=tempGrade;
         }
      }
   }
   

}
void SortByLastName(vector<string> &students, vector<double> &grades){
string lastName1, lastName2;
string temp;
int pos;
double tempGrade;
   for(unsigned int i=0; i<students.size();i++){
      pos=students[i].find(' ');
      lastName1=students[i].substr(pos+1);
      for(unsigned int j=i+1;j<students.size();j++){
         pos=students[j].find(' ');
         lastName2=students[j].substr(pos+1);
         if(lastName1>lastName2){
            temp=students[i];
            students[i]=students[j];
            students[j]=temp;
            tempGrade=grades[i];
            grades[i]=grades[j];
            grades[j]=tempGrade;
         }
      }
   }
}
void SortByGrade(vector<string> &students, vector<double> &grades){
string temp;
double tempGrade;
   
   for(unsigned int i=0;i<students.size();i++){
      for(unsigned int j=i+1;j<students.size();j++){
         if(grades[i]>grades[j]){
            temp=students[i];
            students[i]=students[j];
            students[j]=temp;
            tempGrade=grades[i];
            grades[i]=grades[j];
            grades[j]=tempGrade;
         }
      }
   }
}

Heres an example error output for my current code (for SortByFirstName):

Expected: | | Found:

  • Alyx Masinas | | Alyx Masinas
  • Ginnie McDonald | | Nola Manon
  • Nola Manon | | Ginnie McDonald
  • Randy Rubin | | Randy Rubin
  • Sephora McDonald | | Sephora McDonald

Heres another (for SortByFirstName + SortByGrade):

Expected: | | Found:

  • Alyx Masinas | | Alyx Masinas
  • Ginnie McDonald | | Nola Manon
  • Nola Manon | | Ginnie McDonald
  • Randy Rubin | | Randy Rubin
  • Sephora McDonald | | Sephora McDonald

Expected: | | Found:

  • 83.5 | | 83.5
  • 98.7 | | 100
  • 100 | | 98.7
  • 89.5 | | 89.5
  • 100 | | 100

Why are my functions not sorting properly? After finally getting it to all compile I don't know where to go. Ive been looking in my notes for similar practice problems where the vector was not fully selected during a function call. Any help would be appreciated, thank you.

starball
  • 20,030
  • 7
  • 43
  • 238
3_5
  • 1
  • 1
  • 3
    note the existence of [`std::swap`](https://en.cppreference.com/w/cpp/algorithm/swap) – JHBonarius Oct 28 '20 at 20:44
  • 4
    What does the debugger tell you your code is doing? – JHBonarius Oct 28 '20 at 20:46
  • 1
    are you not allowed to use `std::sort` ? – 463035818_is_not_an_ai Oct 28 '20 at 20:47
  • 2
    Here's some additional info, regarding @JHBonarius comment: https://stackoverflow.com/questions/25385173/what-is-a-debugger-and-how-can-it-help-me-diagnose-problems https://stackoverflow.com/questions/12546706/good-debugger-tutorial-for-beginners – πάντα ῥεῖ Oct 28 '20 at 20:49
  • Well the first set of menu options works fine. When attempting to sort the list, by first name, for example out of 5 names the 2nd and 3rd names are incorrectly not swapped. When sorting by first name and with grades, the same error is apparent, the 2nd and 3rd name/grade on the list do not sort properly (they should be switched). – 3_5 Oct 28 '20 at 20:56
  • I believe we are limited to the scope of selection sort, thats why I haven't wanted to just take an answer from online.. wait hol' up. – 3_5 Oct 28 '20 at 20:58
  • Read this [excellent advice on how to find the problem](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/) – paddy Oct 28 '20 at 21:07
  • no I dont think we can use std:sort – 3_5 Oct 28 '20 at 21:08
  • Why did you edit to delete you code? Please don't vandalize your own post. If there's no code, it's not a [mre]. Note though: you have a lot of code, and I'd encourage trying to narrow down the problem and present less code which still reproduces the issue. – starball Nov 18 '22 at 10:17

1 Answers1

1

In your sort functions' inner loops, you're not taking into account that when you swap two students (e.g. when firstName2 moves into the slot formerly occupied by firstName1) you now need to compare subsequent elements against the new smallest-known entry (firstName2 in this case).

Add one line:

if (firstName1 > firstName2) {
    temp = students[i];
    students[i] = students[j];
    students[j] = temp;
    tempGrade = grades[i];
    grades[i] = grades[j];
    grades[j] = tempGrade;

    // now only look for items that should come before our new "leader"
    firstName1 = firstName2;
}
Paul Roub
  • 36,322
  • 27
  • 84
  • 93