Sorting total and average score of the students and their ranks in ascending order

Hello!

The code below is horrible. I know that. But it's just my assignment and here is the help I seek:

The code itself should open a text file with 15 students' information on their names, scores for math and eng. It then counts total score (like 90 for math and 90 for eng out 100 is 180) and average, and it also shows what rank in the class are they (e.g first place is 198, the second is 195, etc.) I already did all of this and I have prepared text files of these 15 students.

Now, the problem I am facing is sorting their average total and rank in ascending order (each student has numbers 1-15 and now I need to completely ignore their assignment numbers and just focus on their rank order.)

Sorry for writing so boring. I need to clarify all things.
By the way, my professor actually gave a hint about what to do, but I've got no brains for coding, so I am humbly asking for help.
One last thing, the code below is not only a part of the big one (like opening file and pressing buttons, but the adding of hints should be in the part below)
Hint:

 ``12345678910`` ``````void cpyStudentScore(STUDENT_SCORE *d1, STUDENT_SCORE *d2){ d1 ->number = d2->number; strcpy(d1->name,d2->name); d1->kor = d2->kor; d1->eng = d2->eng; d1->math = d2->math; d1->tot = d2->tot; d1->avg = d2->avg; d1->rnk = d2->rnk; }``````

 ``123456789`` ``````for(int i=0; i < stdNum-1; i++){ for(int j=0; j < stdNum-1-i; j++){ if(stdScore[j].tot < stdScore[j+1].tot){ cpyStudentScore(&tmp, &stdScore[j+1].tot); cpyStudentScore(&stdScore[j], &stdScore[j+1]); cpyStudentScore(&stdScore[j+1], &tmp); } } }``````

 ``123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127`` ``````#include "MyInclude.h" #define MAX_STUDENT_NUM 60 typedef struct{ int number; TCHAR name[10]; int kor; int math; int eng; int tot; float avg; int rnk; int *d1; int *d2; }STUDENT_SCORE; extern int readDataAsNum(HWND hSrc, int *data); extern void writeNumToEdit(HWND hDst, int *data, int dataNum); void writeScoreNameToEdit(HWND hDst, STUDENT_SCORE *stdScore, int stdNum); BOOL readScoreNameFromEdit(HWND hSrc, STUDENT_SCORE *stdScore, int *rtnStdNum); void scoreCalculator(HWND hwnd, HWND hSrc, HWND hDst){ TCHAR buff[BUFF_SIZE]; DWORD fileSize; char* tok; int MAX_COL_NUM = 5; int NUMPOS=0, KORPOS=1, MATHPOS=2, ENGPOS=3, TOTPOS=4; int stdScore[MAX_STUDENT_NUM][MAX_COL_NUM], stdNum; fileSize = GetWindowText(hSrc, buff, BUFF_SIZE); buff[fileSize+1] = NULL; stdNum = 0; tok = strtok(buff, "\r\n"); while(tok != NULL){ sscanf(tok,"%d %d %d %d\r\n",&stdScore[stdNum][NUMPOS],&stdScore[stdNum][KORPOS], &stdScore[stdNum][MATHPOS],&stdScore[stdNum][ENGPOS]); tok = strtok(NULL, "\r\n"); stdNum++; if(stdNum >= MAX_PRIME_NUM){ MessageBox(hwnd, "The number of students is out of the storage range.", "Arrangement grade processing.", MB_OK); return; } } for(int i=0; i= MAX_STUDENT_NUM){ return FALSE; } } *rtnStdNum = stdNum; return TRUE; } void writeScoreNameToEdit(HWND hDst, STUDENT_SCORE *stdScore, int stdNum){ TCHAR buff[BUFF_SIZE]; TCHAR str[MAX_DATA_NUM]; sprintf(buff,"%-s\t%-s\t%-s\t%-s\t%-s\t%-s\t%-s\t %-s \r\n", "Number","name","Kor","Math","Eng","Total","Average","Rank"); for(int i=0; i
Last edited on
If you look on the right there is a Format: tool bar. It will help if you go back and edit your post, select your code and then place code tags around it by using the <> button.
Thank you! I just did that
Excellent work with the code tags.

It might be a good idea to post some sample data - just enough to show us so we can conduct a test. Such a .txt file needs to be tagged with the 'Program Output' tag button alonside the <> button.

Also, if it's only the standard includes "MyInclude.h" isn't necessary but otherwise it needs to be posted.
Last edited on
Despite that and the fact that the code is C rather than C++ ... lets look at the "hint":
 ``123456789`` ``````for(int i=0; i < stdNum-1; i++){ for(int j=0; j < stdNum-1-i; j++){ if(stdScore[j].tot < stdScore[j+1].tot){ cpyStudentScore(&tmp, &stdScore[j+1].tot); cpyStudentScore(&stdScore[j], &stdScore[j+1]); cpyStudentScore(&stdScore[j+1], &tmp); } } }``````

The logical operation done by
 ``123`` ``````cpyStudentScore(&tmp, &stdScore[j+1].tot); cpyStudentScore(&stdScore[j], &stdScore[j+1]); cpyStudentScore(&stdScore[j+1], &tmp);``````

is to swap values of two elements (stdScore[j] and stdScore[j+1])

When are they swapped? When condition `stdScore[j].tot < stdScore[j+1].tot` shows that they are not in correct order.

We can see that this condition compares the `.tot`.
We can see that order is incorrect, when tot of j is smaller than tot of j+1. In other words the desired order is descending by the .tot.

If you want ascending order, then you have to change the relation operator (or use NOT).
If you want to sort by other property than .tot, then you adjust the condition accordingly.

The stackoverflow answers show qsort(). C++ has std::sort(). Both take the condition as functor. Both will swap elements with copy/move assignments (although C++ can override swap for custom type).

 ``12345`` ``````STUDENT_SCORE x; STUDENT_SCORE y; // fill x and y with data x = y; // is this copy assignment safe? If not, why? ``````