简体   繁体   中英

Having problems Qsort'ing struct *array based on 2 parameters

Eow, I was working on a program which would take in a.txt with a list of football matches ie team, scores, date etc. and store these in a struct *array (match array). After this I run through the matches and assign points to the teams based on win/draw/loss and also the sum of their goals minus goals against them, these are stored in a struct *array (team array)

Now what i wanna do is sort this array based firstly on points, and if its even then based on the goals sum so the top rated teams is placed first, and the bottom placed team, last.

I'm new to Qsort, so i was wondering what i was messing up here. it seems my data gets completely corrupted.

Any help would be much appreciated

Update: commenter helped me figure out what was corrupting my data which has been fixed now, and also corrected a logic error in my compare_func for qsort, however my qsort still doesnt sort my array in any logical manner, it does however move my structs around. So I'm still looking for some assistance as to why it doesn't properly sort. Code has been updated to reflect changes

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>

#define MSIZE 132
#define TSIZE 12

typedef struct match
{
    char weekday[10], date[10], time[10], home[10], away[10], spectators[10];
    int home_goal, away_goal;
} match;

typedef struct team
{
    char teamname[4];
    int point, goals, goals_against, goals_sum;
} team;

void fill_match_array(match *match_array[MSIZE]);
void allocate_space_team(team *team_array[TSIZE]);
void fill_team_array(team *team_array[TSIZE], match *match_array[MSIZE]);
int compare_function(const void *left, const void *right);



int main(void){
    match *match_array[MSIZE];
    team *team_array[TSIZE];

    allocate_space_team(team_array);
    fill_match_array(match_array);
    for (int i = 0; i < MSIZE; i++)
    {
        printf("%s | %s | %s | %s | %s | - | %d | - | %d | %s\n", match_array[i]->weekday, match_array[i]->date, match_array[i]->time, match_array[i]->home, match_array[i]->away, match_array[i]->home_goal, match_array[i]->away_goal, match_array[i]->spectators);
    }

    printf("\n\n\n\n\n");

    fill_team_array(team_array, match_array);
    for (int i = 0; i < TSIZE; i++)
    {
        printf("%s | %d | %d | %d | %d\n", team_array[i]->teamname, team_array[i]->point, team_array[i]->goals, team_array[i]->goals_against, team_array[i]->goals_sum);
    }
    printf("\n\n\n\n\n");
    qsort(team_array, TSIZE, sizeof(team*), compare_function);
    for (int i = 0; i < TSIZE; i++)
    {
        printf("%s | %d | %d | %d | %d\n", team_array[i]->teamname, team_array[i]->point, team_array[i]->goals, team_array[i]->goals_against, team_array[i]->goals_sum);
    }

    return 0;
}

void fill_match_array(match *match_array[MSIZE]){
    FILE *output_file_pointer;
    output_file_pointer = fopen("kampe-2020-2021.txt", "r");

    char x[5], y[5], home_goal[10], away_goal[10];

    for (int i = 0; i < MSIZE; i++)
    {
        match_array[i] = malloc(sizeof(match));
        fscanf(output_file_pointer, "%s     %s %s     %s %s %s     %s %s %s     %s", match_array[i]->weekday, match_array[i]->date, match_array[i]->time, match_array[i]->home, x, match_array[i]->away, home_goal, y, away_goal, match_array[i]->spectators);
        match_array[i]->home_goal = atoi(home_goal);
        match_array[i]->away_goal = atoi(away_goal);
        //printf("%s | %s | %s | %s | %s | %s | %d | %s | %d | %s\n", match_array[i]->weekday, match_array[i]->date, match_array[i]->time, match_array[i]->home, x, match_array[i]->away, match_array[i]->home_goal, y, match_array[i]->away_goal, match_array[i]->spectators);
    }

    fclose(output_file_pointer);
}

void allocate_space_team(team *team_array[TSIZE]){
    for (int i = 0; i < TSIZE; i++)
    {
        team_array[i] = malloc(sizeof(team));
        team_array[i]->goals = 0;
        team_array[i]->goals_against = 0;
        team_array[i]->goals_sum = 0;
        team_array[i]->point = 0;
    }
    strcpy(team_array[0]->teamname, "SDR");
    strcpy(team_array[1]->teamname, "ACH");
    strcpy(team_array[2]->teamname, "LBK");
    strcpy(team_array[3]->teamname, "BIF");
    strcpy(team_array[4]->teamname, "OB");
    strcpy(team_array[5]->teamname, "AGF");
    strcpy(team_array[6]->teamname, "FCM");
    strcpy(team_array[7]->teamname, "FCK");
    strcpy(team_array[8]->teamname, "RFC");
    strcpy(team_array[9]->teamname, "VB");
    strcpy(team_array[10]->teamname, "AaB");
    strcpy(team_array[11]->teamname, "FCN");
}

void fill_team_array(team *team_array[TSIZE], match *match_array[MSIZE]){
    for (int i = 0; i < TSIZE; i++)
    {
        for (int j = 0; j < MSIZE; j++)
        {
            if (strcmp(team_array[i]->teamname, match_array[j]->home) == 0)
            {
                team_array[i]->goals += match_array[j]->home_goal;
                team_array[i]->goals_against += match_array[j]->away_goal;
                if (match_array[j]->home_goal > match_array[j]->away_goal)
                {
                    team_array[i]->point += 3;
                }
                else if (match_array[j]->home_goal == match_array[j]->away_goal)
                {
                    team_array[i]->point += 1;
                }
            }
            else if (strcmp(team_array[i]->teamname, match_array[j]->away) == 0)
            {
                team_array[i]->goals += match_array[j]->away_goal;
                team_array[i]->goals_against += match_array[j]->home_goal;
                if (match_array[j]->away_goal > match_array[j]->home_goal)
                {
                    team_array[i]->point += 3;
                }
                else if (match_array[j]->home_goal == match_array[j]->away_goal)
                {
                    team_array[i]->point += 1;
                }
            }
        }
        team_array[i]->goals_sum = team_array[i]->goals - team_array[i]->goals_against;
    }
}

int compare_function(const void *left, const void *right){
    const team *a = (const team *)left;
    const team *b = (const team *)right;

    if (a->point > b->point)
    {
        return -1;
    }
    else if (a->point < b->point)
    {
        return 1;
    }
    
    if (a->goals_sum > b->goals_sum)
    {
        return -1;
    }
    else if (a->goals_sum < b->goals_sum)
    {
        return 1;
    }
    else if (a->goals_sum == b->goals_sum)
    {
        return 0;
    }
}

The txt.file to make it run -> should be named "kampe-2020-2021.txt"

Fre     11/09 19.00     SDR - FCM     2 - 0     2210
Son     13/09 14.00     ACH - RFC     0 - 3     1216
Son     13/09 14.00     LBK - AaB     0 - 0     2138
Son     13/09 16.00     BIF - FCN     3 - 2     6775
Son     13/09 18.00     OB - FCK      3 - 2     4315
Man     14/09 19.00     AGF - VB      4 - 2     7547
Lor     19/09 15.30     FCM - LBK     1 - 0     300  
Son     20/09 14.00     FCK - BIF     1 - 2     277  
Son     20/09 14.00     OB - FCN      1 - 1     300  
Son     20/09 16.00     RFC - AGF     1 - 1     300  
Son     20/09 18.00     VB - SDR      4 - 1     350  
Man     21/09 19.00     AaB - ACH     1 - 0     280  
Lor     26/09 17.00     FCM - RFC     1 - 0     300  
Son     27/09 14.00     AGF - OB      4 - 2     300  
Son     27/09 14.00     SDR - AaB     3 - 1     300  
Son     27/09 16.00     BIF - ACH     2 - 1     300  
Son     27/09 18.00     VB - FCK      2 - 2     350  
Man     28/09 19.00     FCN - LBK     4 - 1     300  
Fre     02/10 19.00     RFC - BIF     1 - 2     300  
Son     04/10 14.00     LBK - SDR     2 - 2     300  
Son     04/10 14.00     OB - VB       0 - 1     300  
Son     04/10 16.00     AaB - AGF     1 - 1     280  
Son     04/10 18.00     ACH - FCM     2 - 2     300  
Son     04/10 20.00     FCK - FCN     3 - 2     220  
Lor     17/10 16.00     FCM - OB      3 - 1     300  
Son     18/10 14.00     AGF - ACH     3 - 0     300  
Son     18/10 14.00     VB - LBK      3 - 2     350  
Son     18/10 16.00     SDR - BIF     2 - 0     300  
Son     18/10 18.00     FCK - AaB     1 - 2     242  
Man     19/10 19.00     FCN - RFC     1 - 0     300  
Fre     23/10 19.00     LBK - OB      0 - 3     300  
Lor     24/10 18.00     BIF - FCM     2 - 3     300  
Son     25/10 14.00     ACH - FCN     1 - 1     300  
Son     25/10 16.00     RFC - SDR     1 - 2     300  
Son     25/10 18.00     AGF - FCK     0 - 1     300  
Man     26/10 19.00     AaB - VB      1 - 3     300  
Fre     30/10 19.00     VB - RFC      0 - 3     350  
Lor     31/10 16.00     FCN - FCM     4 - 1     300  
Son     01/11 14.00     OB - ACH      1 - 0     300  
Son     01/11 16.00     FCK - LBK     4 - 2     247  
Son     01/11 18.00     AaB - BIF     2 - 1     300  
Man     02/11 19.00     SDR - AGF     1 - 1     300  
Fre     06/11 19.00     RFC - AaB     1 - 2     300  
Son     08/11 14.00     FCN - VB      1 - 1     300  
Son     08/11 14.00     LBK - AGF     1 - 2     300  
Son     08/11 16.00     BIF - OB      3 - 1     300  
Son     08/11 18.00     FCM - FCK     4 - 0     300  
Son     08/11 20.00     ACH - SDR     0 - 3     300  
Fre     20/11 19.00     LBK - ACH     1 - 1     300  
Son     22/11 14.00     OB - SDR      1 - 1     300  
Son     22/11 14.00     AaB - FCN     1 - 1     300  
Son     22/11 16.00     AGF - FCM     1 - 2     300  
Son     22/11 18.00     VB - BIF      0 - 2     350  
Man     23/11 19.00     FCK - RFC     1 - 2     246  
Fre     27/11 19.00     RFC - OB      2 - 1     300  
Lor     28/11 16.00     FCM - AaB     0 - 0     300  
Son     29/11 14.00     ACH - VB      3 - 1     300  
Son     29/11 16.00     SDR - FCK     1 - 3     300  
Son     29/11 18.00     FCN - AGF     3 - 1     300  
Man     30/11 19.00     BIF - LBK     4 - 1     300  
Fre     04/12 19.00     OB - AaB      2 - 1     300  
Lor     05/12 16.00     VB - FCM      0 - 2     350  
Son     06/12 14.00     SDR - FCN     2 - 1     300  
Son     06/12 16.00     FCK - ACH     2 - 0     226  
Son     06/12 18.00     LBK - RFC     0 - 3     300  
Man     07/12 19.00     AGF - BIF     3 - 1     300  
Fre     11/12 19.00     RFC - VB      3 - 1     300  
Son     13/12 14.00     ACH - AGF     1 - 2     300  
Son     13/12 14.00     AaB - LBK     3 - 2     300  
Son     13/12 16.00     FCN - FCK     0 - 1     300  
Son     13/12 18.00     BIF - SDR     2 - 1     300  
Man     14/12 19.00     OB - FCM      1 - 1     300  
Son     20/12 14.00     SDR - RFC     0 - 1     300  
Son     20/12 14.00     LBK - VB      0 - 0     300  
Son     20/12 16.00     AGF - AaB     3 - 0     300  
Son     20/12 18.00     FCK - OB      1 - 1     242  
Son     20/12 20.00     ACH - BIF     1 - 2     300  
Man     21/12 19.00     FCM - FCN     3 - 1     300  
Tir     02/02 18.00     RFC - ACH     3 - 0     0    
Tir     02/02 20.00     VB - AGF      0 - 0     0    
Ons     03/02 18.00     OB - LBK      0 - 1     0    
Ons     03/02 20.00     AaB - FCK     2 - 3     0    
Tor     04/02 18.00     FCM - SDR     1 - 2     0    
Tor     04/02 20.00     FCN - BIF     0 - 1     0    
Son     07/02 14.00     SDR - VB      0 - 1     0    
Son     07/02 14.00     FCN - OB      0 - 2     0    
Son     07/02 16.00     ACH - FCK     0 - 2     0    
Son     07/02 18.00     AGF - LBK     1 - 0     0    
Son     07/02 20.00     BIF - AaB     1 - 1     0    
Man     08/02 19.00     RFC - FCM     1 - 2     0    
Son     14/02 14.00     AaB - RFC     0 - 0     0    
Son     14/02 14.00     VB - FCN      2 - 2     0    
Son     14/02 16.00     LBK - BIF     0 - 4     0    
Son     14/02 18.00     FCM - ACH     1 - 0     0    
Son     14/02 20.00     OB - AGF      0 - 0     0    
Man     15/02 19.00     FCK - SDR     3 - 2     0    
Fre     19/02 19.00     AaB - FCM     0 - 2     0    
Son     21/02 14.00     RFC - FCN     1 - 1     0    
Son     21/02 14.00     ACH - OB      0 - 0     0    
Son     21/02 16.00     AGF - SDR     2 - 0     0    
Son     21/02 18.00     BIF - VB      2 - 1     0    
Man     22/02 19.00     LBK - FCK     2 - 2     0    
Fre     26/02 19.00     VB - ACH      0 - 0     0    
Son     28/02 14.00     OB - RFC      2 - 1     0    
Son     28/02 14.00     FCN - AaB     2 - 2     0    
Son     28/02 16.00     FCK - AGF     3 - 3     0    
Son     28/02 18.00     FCM - BIF     1 - 0     0    
Man     01/03 19.00     SDR - LBK     1 - 4     0    
Ons     03/03 18.00     AGF - FCN     0 - 1     0    
Ons     03/03 18.00     ACH - AaB     2 - 1     0    
Ons     03/03 20.00     FCK - VB      2 - 1     0    
Tor     04/03 18.00     SDR - OB      1 - 1     0    
Tor     04/03 18.00     LBK - FCM     2 - 0     0    
Tor     04/03 20.00     BIF - RFC     0 - 0     0    
Son     07/03 12.00     RFC - LBK     1 - 2     0    
Son     07/03 14.00     BIF - FCK     2 - 1     0    
Son     07/03 16.00     FCM - AGF     0 - 1     0    
Son     07/03 18.00     FCN - ACH     2 - 2     0    
Son     07/03 20.00     VB - OB       2 - 0     0    
Man     08/03 19.00     AaB - SDR     1 - 0     0    
Fre     12/03 19.00     LBK - FCN     0 - 3     0    
Son     14/03 14.00     SDR - ACH     2 - 0     0    
Son     14/03 14.00     VB - AaB      0 - 2     0    
Son     14/03 16.00     OB - BIF      0 - 3     0    
Son     14/03 18.00     FCK - FCM     0 - 0     0    
Man     15/03 19.00     AGF - RFC     1 - 1     0    
Son     21/03 17.00     BIF - AGF     1 - 1     0    
Son     21/03 17.00     FCM - VB      5 - 0     0    
Son     21/03 17.00     RFC - FCK     2 - 1     0    
Son     21/03 17.00     ACH - LBK     1 - 2     0    
Son     21/03 17.00     FCN - SDR     2 - 1     0    
Son     21/03 17.00     AaB - OB      0 - 2     0    

team_array is an array of pointers to a team. So a pointer to an element in that array will be a pointer to a pointer to a team.

int compare_function(const void *left, const void *right) {
    const team *const *apnt = left;
    const team *const *bpnt = right;
    const team *a = *apnt;
    const team *b = *bpnt;

Overall, in your code, I see no reason for using any arrays of pointers and even to dynamically allocate memory. If you know the size of memory you are going to allocate, there is no reason to use dynamic allocation. Remove all the pointers, change all the -> into . and just use normal arrays.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM