Preface: Guidelines set by professor, I must use the array, not some other data structure. His psuedo code (which isn't very concise) of the method we should be following:
name and grade are read into a temporary location
loop from the end of the filled part of the array down to beginning {
if (new last name < current last name) {
copy current name and grade down
}
else if (new/current last names are equal and new first name < current first name) {
copy/assign current name and grade down
}
else {
found right place, break out of loop
}
}
now that you've made room, insert (copy) new name into correct sorted position
I see that I'm probably breaking array bounds by attempting to read array position [-1] but I can't think of a way to avoid that since I'm counting backwards from the number of items I have and have to compare them.
I'm reading lines from a text file and storing pieces of each line into a struct. Then I'm using an insertion-sort-esque algorithm to store the structs in alphabetical order. However, my array does not seem to populate past the first couple lines with the new lines simply overwriting the previous lines... It's as if one of my comparison tests is failing since my copy position never appears to change although that could be because the initial array populating is failing in some way. I feel foolish, I must be missing something simple... Also my DisplayList module apparently never gets an array that's been populated with anything. Am I altering the array in an incorrect manner?
Here is the module with the problem:
bool sortInput(ifstream &infile, StudentType students[], int size)
{
StudentType temp;
int copyToHere;
if(size == 0)
{
infile >> temp.last >> temp.first >> temp.grade;
strcpy(students[0].last, temp.last);
strcpy(students[0].first, temp.first);
students[0].grade = temp.grade;
size++;
}
while(infile)
{
infile >> temp.last >> temp.first >> temp.grade;
//cout << "TEST" << temp.last << temp.first << temp.grade << endl;
for(int i = size; i > 0; i--)
{
if(strcmp(temp.last, students[i-1].last) < 0)
{
students[i] = students[i-1];
students[i-1] = temp;
}
else if(strcmp(temp.last, students[i].last) == 0 && strcmp(temp.first, students[i].first) < 0)
{
students[i] = students[i-1];
}
else
{
break;
}
copyToHere = i;
}
cout << "Size = " << size << " and copy position = " << copyToHere << endl;
students[copyToHere] = temp;
size++;
//test to see if array is populated properly
for(int i = 0; i < size; i++)
{
cout << "Name is " << students[i].first << " " << students[i].last << " and grade is " << students[i].grade << endl;
}
cout << "DONE" << endl;
} //end while loop
return true;
}
Here is the full code (if necessary for whatever reason or further context):
// ----------------------------------------------------------------------------
// You write meaningful doxygen comments and assumptions
#include <string.h>
#include <iostream>
#include <iomanip>
#include <fstream>
using namespace std;
int const MAXSIZE = 100; // maximum number of records in total
int const MAXLENGTH = 31; // maximum string length
int const MAXGRADE = 100; // highest possible grade
int const LOWGRADE = 0; // lowest possible grade
int const GROUP = 10; // group amount
int const HISTOGRAMSIZE = (MAXGRADE-LOWGRADE)/GROUP + 1; // grouped by GROUP
struct StudentType { // information of one student
int grade; // the grade of the student
char last[MAXLENGTH]; // last name (MAXLENGTH-1 at most)
char first[MAXLENGTH]; // first name (MAXLENGTH-1 at most)
};
// prototypes go here
bool sortInput(ifstream &, StudentType [], int);
void displayList(StudentType [], int);
/*setHistrogram();
displayHistogram();
findAverage();*/
//------------------------------- main ----------------------------------------
int main() {
StudentType students[MAXSIZE]; // list of MAXSIZE number of students
int size = 0; // total number of students
int histogram[HISTOGRAMSIZE]; // grades grouped by GROUP
int average = 0; // average exam score, truncated
// creates file object and opens the data file
ifstream infile("data1.txt");
if (!infile) {
cout << "File could not be opened." << endl;
return 1;
}
// read and sort input by last then first name
bool successfulRead = sortInput(infile, students, size);
// display list, histogram, and class average
if (successfulRead) {
displayList(students, size);
// setHistogram(... you figure parameters ...);
// displayHistogram(... you figure parameters ...);
// average = findAverage(... you figure parameters ...);
cout << "Average grade: " << average << endl << endl;
}
return 0;
}
bool sortInput(ifstream &infile, StudentType students[], int size)
{
StudentType temp;
int copyToHere;
if(size == 0)
{
infile >> temp.last >> temp.first >> temp.grade;
strcpy(students[0].last, temp.last);
strcpy(students[0].first, temp.first);
students[0].grade = temp.grade;
size++;
}
while(infile)
{
infile >> temp.last >> temp.first >> temp.grade;
//cout << "TEST" << temp.last << temp.first << temp.grade << endl;
for(int i = size; i > 0; i--)
{
if(strcmp(temp.last, students[i-1].last) < 0)
{
students[i] = students[i-1];
students[i-1] = temp;
}
else if(strcmp(temp.last, students[i].last) == 0 && strcmp(temp.first, students[i].first) < 0)
{
students[i] = students[i-1];
}
else
{
break;
}
copyToHere = i;
}
cout << "Size = " << size << " and copy position = " << copyToHere << endl;
students[copyToHere] = temp;
size++;
//test to see if array is populated properly
for(int i = 0; i < size; i++)
{
cout << "Name is " << students[i].first << " " << students[i].last << " and grade is " << students[i].grade << endl;
}
cout << "DONE" << endl;
} //end while loop
return true;
}
void displayList(StudentType students[], int size)
{
cout << "List of names sorted:" << endl;
for(int i = 0; i < size; i++)
{
cout << " " << students[i].grade << " " << students[i].last << " " << students[i].first << endl;
}
}
// ----------------------------------------------------------------------------
// functions with meaningful doxygen comments and assumptions go here