c++ - How do I read an array of structs from a file and sort it? -
preface: guidelines set professor, must use array, not other data structure. psuedo code (which isn't concise) of method should following:
name , grade read temporary location loop end of filled part of array down beginning { if (new last name < current last name) { copy current name , grade down } else if (new/current last names equal , new first name < current first name) { copy/assign current name , grade down } else { found right place, break out of loop } } you've made room, insert (copy) new name correct sorted position
i see i'm breaking array bounds attempting read array position [-1] can't think of way avoid since i'm counting backwards number of items have , have compare them.
i'm reading lines text file , storing pieces of each line struct. i'm using insertion-sort-esque algorithm store structs in alphabetical order. however, array not seem populate past first couple lines new lines overwriting previous lines... it's if 1 of comparison tests failing since copy position never appears change although because initial array populating failing in way. feel foolish, must missing simple... displaylist module apparently never gets array that's been populated anything. altering array in incorrect manner?
here module 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 = size; > 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 << " , copy position = " << copytohere << endl; students[copytohere] = temp; size++; //test see if array populated for(int = 0; < size; i++) { cout << "name " << students[i].first << " " << students[i].last << " , grade " << students[i].grade << endl; } cout << "done" << endl; } //end while loop return true; }
here full code (if necessary whatever reason or further context):
// ---------------------------------------------------------------------------- // write meaningful doxygen comments , 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 group struct studenttype { // information of 1 student int grade; // grade of student char last[maxlength]; // last name (maxlength-1 @ most) char first[maxlength]; // first name (maxlength-1 @ 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 group int average = 0; // average exam score, truncated // creates file object , opens data file ifstream infile("data1.txt"); if (!infile) { cout << "file not opened." << endl; return 1; } // read , sort input last first name bool successfulread = sortinput(infile, students, size); // display list, histogram, , class average if (successfulread) { displaylist(students, size); // sethistogram(... figure parameters ...); // displayhistogram(... figure parameters ...); // average = findaverage(... 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 = size; > 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 << " , copy position = " << copytohere << endl; students[copytohere] = temp; size++; //test see if array populated for(int = 0; < size; i++) { cout << "name " << students[i].first << " " << students[i].last << " , grade " << 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 = 0; < size; i++) { cout << " " << students[i].grade << " " << students[i].last << " " << students[i].first << endl; } } // ---------------------------------------------------------------------------- // functions meaningful doxygen comments , assumptions go here
your insertion sort isn't inserting properly. let's @ 1 part of main insertion loop:
if(strcmp(temp.last, students[i-1].last) < 0) { students[i] = students[i-1]; students[i-1] = temp; }
the intention of insert temp
array @ position i-1
. you're shifting item @ i-1
i
happened other elements in array? need move them 1 position make room inserted element. like:
memmove(students + i, students + - 1, sizeof(students[0]) * size - - 1);
you have other problems in code too. copytohere
potentially uninitialized. copying temp
array multiple times (students[i-1] = temp;
, students[copytohere] = temp;
aren't both needed). once have done insertion in inner loop should break out. special handling when list empty isn't necessary, , on.
have @ pseudo-code insertion sort algorithm , see if can simplify , rewrite yours eliminate problems.
Comments
Post a Comment