C . I'm tring to get records from a file and store a sorted copy to a different file.
When I call the void sort(Student A[], int count) function with sort(newStudent, Student::getnStudents()); the program will crash if the second argument is over 3 (no errors/warnings).
After sort is called, some entries will have their classList[0] be complete gibberish symbols. Not sure why. I used const for the overloaded <. Commenting out sort has the program run as expected.
#include <iostream>
#include <fstream> //for input output files
using namespace std;
#include "student.h"
#include "student.cpp"
// Inputs students from a text file using "lname fname n (list of n classes)" and sorts them to a seperate text file.
// Includes statistics about classes and the number of students taking each class.
//==================================================
void sort(Student A[], int count) { // Sort function // <- PROBLEM
for (int i=1; i<count; i ) {
for (int j=i; (j>0) && (A[j] < A[j-1]); j--) {
swap(A[j],A[j-1]);
}
}
}
//==================================================
int main(int argc, char *argv[]) {
if (argc != 4) {
cout << "Usage: " << argv[0] << " (input) (output) (# of elements)" << endl;
exit(1);
}
// Variables from argv. input/output location and max elements for Student
string inputFile = argv[1];
string outputFile = argv[2];
int maxStudents = atoi(argv[3]);
// Array to calculate class statistics
int numberClasses[6] = {0};
string classNames[6] = {"CSC121", "CSC127", "CSC275", "CSC375", "CSC377", "CSC381"};
// Array that is a copy of numberClasses
int numberClasses2[6];
// Most and least common classes
string mostCommon;
string leastCommon;
// Average number of classes per student
float avgClasses = 0.0;
// Student array
Student *newStudent;
newStudent = new Student[maxStudents];
//==================================================
ifstream inStream;
inStream.open(inputFile);
for (int i=0; i<maxStudents; i ) {
inStream>>newStudent[i];
}
inStream.close();
//==================================================
ofstream outStream;
outStream.open(outputFile);
for(int i=0; i<Student::getnStudents(); i ) { // TEST BEFORE
cout<<newStudent[i]<<endl;
}
sort(newStudent, Student::getnStudents()); // <- THIS IS THE PROBLEM
cout<<endl;
for(int i=0; i<Student::getnStudents(); i ) { // TEST AFTER
cout<<newStudent[i]<<endl;
}
for(int i=0; i<Student::getnStudents(); i ) {
outStream<<newStudent[i]<<endl;
}
outStream.close();
//==================================================
// Go through student array and their class list to increase the corresponding numberClasses array. EX: numberClasses[0] = classNames[0].
for(int i=0; i<Student::getnStudents(); i ) {
for (int j=0; j<newStudent[i].getnclasses(); j ) {
for (int k=0; k<6; k ) {
if (newStudent[i].getclassList(j) == classNames[k]) {numberClasses[k] ;}
}
}
}
// loop to print statistics of number of students taking each class
for (int i=0; i<6; i ) {
cout<<endl<<"Number of students taking "<<classNames[i]<<": "<<numberClasses[i];
}
//==================================================
for (int i=0; i<6; i ) {
numberClasses2[i] = numberClasses[i];
}
// Sort numberClasses2
for (int i=0; i<6; i ) {
for (int j=i; (j>0) && (numberClasses2[j] < numberClasses2[j-1]); j--) {
swap(numberClasses2[j],numberClasses2[j-1]);
}
}
// Compare numberClasses2 to numberClasses
for (int i=0; i<6; i ) {
if (numberClasses2[6-1] == numberClasses[i]) {
mostCommon = classNames[i];
}
if (numberClasses2[0] == numberClasses[i]) {
leastCommon = classNames[i];
}
}
// Calculate average classes taken per student
for (int i=0; i<Student::getnStudents(); i ) {
avgClasses = newStudent[i].getnclasses();
}
avgClasses = avgClasses/Student::getnStudents();
//==================================================
// Print rest of statistics
cout<<endl<<"Most common course: "<<mostCommon;
cout<<endl<<"Least common course: "<<leastCommon;
cout<<endl<<"Average number of courses taken, per student: "<<avgClasses;
return 0;
}
#ifndef STUDENT_H
#define STUDENT_H
class Student {
public:
Student(); // Constructor
~Student(); // Destructor
// Accessors
string getclassList(int idx) { return classList[idx]; }
static int getnStudents(){return nStudents;}
int getnclasses(){return nclasses;}
// Overloaded I/O stream operators
friend istream& operator>> (istream&, Student&);
friend ostream& operator<< (ostream&, const Student&);
// Overloaded compare
friend bool operator < (const Student& S1, const Student& S2);
private:
string lname; // Person's last name
string fname; // Person's first name
int nclasses; // Number of courses enrolled in
string *classList; // An array of strings for names of courses enrolled in
// Static variables for # of students
static int nStudents;
};
int Student::nStudents = 0;
#endif
#include "student.h"
using namespace std;
// Destructor
Student::~Student() {
delete[] classList;
classList = NULL;
}
// Default constructor
Student::Student() : fname("First"), lname("Last") {
classList = new string[6];
}
//==================================================
// Overloaded input
istream& operator >> (istream& inputStream, Student& S){
inputStream >> S.lname;
inputStream >> S.fname;
inputStream >> S.nclasses;
for (int i=0; i<S.nclasses; i ) {
inputStream >> S.classList[i];
}
if (S.nclasses>0) {Student::nStudents ;}
return inputStream;
}
// Overloaded output
ostream& operator<< (ostream& outputStream, const Student& S){
outputStream<<S.lname<<" "<<S.fname<<" "<<S.nclasses;
for (int i=0; i<S.nclasses; i ) {
outputStream<<" "<<S.classList[i];
}
return outputStream;
}
//==================================================
// Overloaded compare
bool operator < (const Student& S1, const Student& S2) {
if (S1.lname == S2.lname) {
return (S1.fname <= S2.fname);
}
return (S1.lname < S2.lname);
}
I've tried changing the sort function. Changing the overloaded < compare. Making lname public and comparing lname of two Student Arrays in the sort function without an overloaded <. This used to work, but then I changed something and now I can't figure out what else to do to fix it.
CodePudding user response:
Looks like you implement sorting not correct. Looks like you try to implement Selection Sort.
void selectionSort(Student A[], int count) {
for (int i = 0; i < count; i ) {
for (int j = i 1; j < count; j ) {
if (A[j] < A[i]) {
swap (A[i], A[j]);
}
}
}
}
CodePudding user response:
The issue was the classList member variable (part of the class I was trying to sort) is a raw pointer and does not follow the rule of three. I modified that variable and now it works.