0

I do not know how to use sort() to list the student names in alphabetical order. I know the general format of it, my prof gave us a page showing it as sort(array.begin(), array.end());

I This code is honestly beyond what we've learned in class (it's only our 2nd assignment of the semester, and my 2nd programming class overall lol) and I've taught myself what I can through YouTube and this site (among so many others) but I'm having a hard time getting this requirement done.

If it helps, the names do not need to be user inputted, they can be initialized and used that way instead. I just found user input easier. Thank you.

header file:

// Definition of class GradeBook that uses an array to store test grades.
#include<string>
#include<iostream>
#include<array>
#include<iomanip> //parameterized stream manipulators
#include<algorithm> //for .sort() .end()
using namespace std;

//GradeBook class definition
class GradeBook{
public:

  //constant number of students who took the test
  static const size_t students{10}; //note public data

  //constructor initializes courseName and grades array
  

    GradeBook(const string& name, const array <int, students>& gradesArray) //array of type int named gradesArray, size of 'students' (10)
    : courseName{name}, grades{gradesArray} {  }
    
    struct studentInfo
    {
        string studentName;
        int grade;
    };

  //function to set the course name
  void setCourseName(const string& name)
  {courseName = name; //store the course name
  } 

  //function to retrieve the course name
  const string& getCourseName() const {
    return courseName;
  }

  //display a welcome message to the GradeBook user
  void displayMessage() const{
    //call getCourseName to get the name of this GradeBooks course
    cout << "Welcome to the grade book for \n" << getCourseName() 
      << "!" << endl;
  }

  //perform various operations on the data (none modify the data)
  void processGrades() const {
    outputGrades(); //output grades array

    //call function getAverage to calculate the average grade
    cout << setprecision(2) << fixed;
    cout << "\nClass average is " <<getAverage() <<endl;

    //call functions getMinimum and getMaximum
    cout <<"Lowest grade is " << getMinimum()
    <<"\nHighest grade is "<< getMaximum() <<endl;
    
    outputBarChart(); //display grade distribution chart
  }

  //find minimum grade
  int getMinimum() const{
    int lowGrade{100}; //assume lowest grade is 100

    //loop through grades array
    for(int grade : grades){
      //if current grade lower than lowGrade, assign it to lowGrade
      if (grade < lowGrade){
          lowGrade = grade; //new lowest grade        
      }//end if
    }//end for

    return lowGrade;//return lowest grade
  }//end 'getMinimum'

  //find maximum grade
  int getMaximum() const {
    int highGrade{0};//assume highest grade is 0

    //loop through grades array
    for (int grade : grades){
      //if current grade higher than highGrade, assign it to highGrade
      if (grade > highGrade){
        highGrade = grade; //new highest grade        
      }//end if
    }//end for
    
    return highGrade; //return highest grade
  }//end 'getMaximum'

  //determine average grade for test
  double getAverage() const {
    int total{0};//initialize total

    //sum grades in array
    for (int grade : grades){
      total += grade;
    }//end for

    //return average of grades
    return static_cast<double>(total) / grades.size();
  }//end 'getAverage'

  //output bar chart displaying grade distribution
  void outputBarChart() const{
    cout << "\nGrade distribution:" <<endl;

    //stores frequency of grades in each range of 10 grades
    const size_t frequencySize{11};
    array<unsigned int, frequencySize> frequency{}; //init to 0s

    //for each grade, icnrement the appropriate frequency
    for (int grade : grades){
      ++frequency[grade / 10];
    }//end for

    //for each grade frequency, print bar in chart
    for (size_t count{0}; count < frequencySize; ++count){
      //output bar labels ("0-9:", ..., "90-99:", "100:")
      if (0 == count){
        cout << " 0-9: ";
      }//end if
      else if(10 == count){
        cout << " 100: ";
      }//end else if
      else{
        cout << count * 10 << "-" << (count * 10) + 9 << ": ";
      }//end else

      //print bar of asteriks
      for(unsigned int stars{0}; stars < frequency[count]; ++stars){
         cout <<'*'; 
      }//end for

      cout << endl; //start a new line of output
    }//end for
  }//end 'outputBarChart'
  



  //output the contents of the grades array
  void outputGrades() const{
        int i;
        studentInfo info[ students ]; 
        
        //collect names from user
        for(int i=0; i < students; i++)
        {
            cout << "\nEnter name of student " << i+1 << ": ";
            getline(cin, info[i].studentName);
        }//end for
        
        
        cout << endl << "\nStudent roster:\n";
        
            //output each students grades
            for (size_t student{0}; student < grades.size(); ++student){ 
                cout << "Student " << setw(2) << info[student].studentName << ": "
                << setw(3) << grades[student] << endl;
            }//end for

  }//end 'outputGrades'



private:

  string courseName; //course name for this grade book
  array<int, students> grades; // array of type int called 'grades' of size 'students'(10)
  
};//end class 'GradeBook'

Main:

//GradeBook.cpp
#include<iostream>
#include <array>
#include<string>
#include<algorithm>
#include "Gradebook2.h" //GradeBook class defintion


int main() {
  //array of student grades
  const array<int, GradeBook::students> grades{ 87, 68, 94, 100, 83, 78, 85, 91, 76, 87};
       
  string courseName{"COSC 1337"};

  GradeBook myGradeBook(courseName, grades);
  myGradeBook.displayMessage();
  myGradeBook.processGrades();

}//end main

I reached out to one of the tutors for my class and all they advised is that the function outputGrades() is const, so I need to use sort() in a separate function. I really can't wrap my head around how to do it.

2
  • I provided an answer below. But I wasn't sure which "array" or variable in your code you wanted to sort on. I was assuming the info array in outputGrades Commented Feb 26, 2023 at 3:56
  • Also, pro-tip. All those "// end for" like comments are severely muddling up your code. If you were consistently identing correctly, it would read much easier. C++ often looks best with a 4 space indent, but that's just my opinion. Commented Feb 26, 2023 at 4:04

1 Answer 1

0

If you have a classic "C" style array like this:

studentInfo info[ students ];

Then you can pass the start and end boundaries as pointers and pointer arithmetic. But you'll need to provide a comparison function for comparing your own structs. That's often done with a lambda.

auto compareStudent = [](const studentInfo& s1, const studentInfo& s2) {
    return (s1.name < s2.name);
};
std::sort(info, info+students, compareStudent);

If you have a std::array like this:

std::array<studentInfo, students> info;

Then with the same lambda, compareStudent, you can use the begin/end methods:

std::sort(info.begin(), info.end(), compareStudent);

But be advised - this will expose a bug in your outputGrades function when you go to print grades[student]. Because your grades array is no longer sorted in the same order as your info array. There's a very trivial fix for that.

Sign up to request clarification or add additional context in comments.

2 Comments

Arguably std::vector is a better choice then std::array (because a program with a fixed size number of students isn't all that flexible).
@PepijnKramer - no disagreement. I just didn't want to implement the OP's entire homework for them. I'm assuming the hardcoded limit of 10 is a requirement of the academic exercise. If not, OP should switch from array to vector.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.