Thread: C Program for sorting teams

  1. #1
    Registered User
    Join Date
    Jun 2019
    Posts
    3

    C Program for sorting teams

    Hey guys. I'm new in programming in general so I need some help. Basically, I'm still practicing before my 'exams' and I got a task to make a program in which we are using files and structures and it says that we have a file which contains rows of data about volleyball players (first name, last name, points, name of the team). The first part of the task is to find the player with most points scored and to print his name and score. I have done this part already.

    The second part which I have problems with is to find team with most points. So, as said in the task, we get files and cannot see how many players there are, or count how many teams there are etc. Also, there are more than one players of the same team in the file, so I have to find sum of all players' scores and I have to divide it by teams. Team names are given as strings.

    I hope I explained everything. I'm not a native English speaker so if I made some mistakes, forgive me

    EDIT: I don't want you to do whole task for me, just the code for the team score part. TY

    EDIT#2: Ye, nooo, sorry, what I meant there is just tell me how to do it, you don't have to do it for mee LOL
    Last edited by brtmoi; 06-24-2019 at 04:27 PM.

  2. #2
    Registered User catacombs's Avatar
    Join Date
    May 2019
    Location
    /home/
    Posts
    81
    Do you have examples of the data file? I'd love to do this on my own and see if I can find a solution.

  3. #3
    Registered User
    Join Date
    Dec 2017
    Posts
    952
    @catacombs, It presumably looks something like this:
    Code:
    A B 123 Blue
    C D 210 Red
    E F 187 Blue
    G H 271 Green
    I J 194 Red
    K L 173 Green
    Where A B C D ... are standing in for first and last names and the colors are team names.

    @brtmoi, Are you thinking of reading the entire file into an array of structs, sorting that array by team names to bring players on the same team together, and then determining the highest team score from that?

    Where are you having problems? Can you read it in? Do you know how to use qsort?
    Last edited by john.c; 06-24-2019 at 05:41 PM.
    If you want the truth to stand clear before you, never be for or against. - Sent-ts'an

  4. #4
    Registered User
    Join Date
    Jun 2019
    Posts
    3
    @john.c Yes that is exactly the data file example.

    I have done already the part with best player, and I just need to find which is the best team amongst players. So I have to somehow divide all players' scores to different teams.
    So in this case, with this example up there, we have blue team with 310 points, red with 404, green with 444 points, and I program just needs to find the best team, which in this case is green team, and to print that.
    The part that confuses me is how to add points to different teams without knowing either their names or ID numbers or something like that.

    I made structure like this
    Code:
    typedef struct players
    {
        char FirstName[15];
        char LastName[15];
        int Points;
    char Team[15];
    }PLAYERS;
    I scanned whole file into array of structures, found the best player, and just the team score is left to do. If you want I will post my whole program.

  5. #5
    Registered User
    Join Date
    Apr 2019
    Posts
    662
    do you know the names of all the teams in the list and or how many teams there are.

    if you do then simply look for the team name and add the scores to the appropriate tally... for example
    Code:
    if (my var == Blue)
    {
       blue score = myscorevar)
    }
    where my var is the team name of the record you are reading and my score var is the score of the current record.
    hope this helps
    coop

  6. #6
    Registered User
    Join Date
    Jun 2019
    Posts
    3
    I'm not sure why my previous post is not here.. I will explain again..

    @john.c Yes, that is exactly how file looks like, well, what it's supposed to look like.. FIRST_NAME LAST_NAME POINTS TEAM_NAME
    I made a array of structures with 4 variables, first name, last name, total points and team name and I scanned whole file into it. I've already made for loop for finding the best player and function to print his name and points.

    @cooper1200 I appreciate the help, that would be pretty easy if I knew team names and how much teams there is actually, but I don't. It could be 20 players with 2 teams, or it could be thousands of players with hundreds of teams... That is the part that confuses me...

  7. #7
    Registered User catacombs's Avatar
    Join Date
    May 2019
    Location
    /home/
    Posts
    81
    This was an interesting challenge. I spent the morning implementing my own solution. This program can take in a different number of players from a seperate file. I set the initial value for TEAM_ALLOCATION, to number of players in a dynamically allocated list, to 500, but that can be adjusted if OP suspects the file will be huge.

    Using this file:

    Code:
    Alpha Bravo 123 Blue
    Charlie Delta 210 Red
    Echo Foxtrot 187 Blue
    Gecko Helio 271 Green
    Indigo Juliet 194 Red
    Kilo Lima 173 Green
    Monsoon Neptune 300 Black
    Oscar Pluto 898 Green
    Queen Roger 221 Black
    Small Television 12 Blue
    Uniform Victor 900 Green
    William Xray 40 Yellow
    Yellow Zebra 300 Black

    fed into this program:

    Code:
    #include <fcntl.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/mman.h>
    #include <sys/stat.h>
    
    #define WORD_SIZE 100
    #define TEAM_ALLOCATION 500
    
    typedef struct {
        char full_name[WORD_SIZE];
        int score;
        char team[WORD_SIZE];
    } Player;
    
    typedef struct {
        int score;
        char team[WORD_SIZE];
    } Team;
    
    // return the text that is in data file
    char* get_file_content(char* path)
    {
        struct stat sb;
        int fd = open(path, O_RDONLY, S_IRUSR | S_IWUSR);
    
        if (fstat(fd, &sb) == -1) {
            perror("coudn't get file size. \n");
        }
    
        char* file = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
        char* text = malloc(sb.st_size * sizeof(char*));
    
        strcpy(text, file);
    
        return text;
    }
    
    // split the text, add to Player struct
    // and append Player items to Player array
    void split_text(char* text, Player* players, int* player_count)
    {
    
        char* re = "\n";
        char* token = strtok(text, re);
    
        while (token != NULL) {
    
            Player player;
            Player* p = &player;
    
            int score;
            char first[WORD_SIZE];
            char last[WORD_SIZE];
            char full_name[WORD_SIZE];
            char team[WORD_SIZE];
    
            // extract from each line
            sscanf(token, "%s %s %d %s", first, last, &score, team);
    
            // dump into full_name text buffer
            sprintf(full_name, "%s %s", first, last);
    
            // add full name to player struct
            strcpy(p->full_name, full_name);
    
            // add team name
            strcpy(p->team, team);
    
            // add score
            p->score = score;
    
            // add Player instance
            // to array
            players[*player_count] = *p;
    
            // increment player_counter
            (*player_count)++;
    
            // reset split
            token = strtok(NULL, re);
        }
    }
    
    // get the highest-scoring player
    // from the array of players
    Player get_highest_scorer(Player* players, int player_count)
    {
        int max = 0;
        int maxIndex;
    
        for (int i = 0; i < player_count; i++) {
    
            int score = players[i].score;
    
            if (score == 0) {
                break;
            }
    
            if (score > max) {
                max = score;
                maxIndex = i;
            }
        }
    
        return players[maxIndex];
    }
    
    // get a list of unique team names
    void get_unique_teams(Player* players, int player_count, int* unique_count, char** uniques)
    {
        int i, j;
    
        *unique_count = 0;
        for (i = 0; i < player_count; i++) {
    
            char* pit = players[i].team;
    
            for (j = i + 1; j < player_count; j++) {
    
                char* pjt = players[j].team;
    
                if (strcmp(pit, pjt) == 0) {
                    /* Duplicate element found */
                    break;
                }
            }
            /* If j is equal toplayer_count, it means we traversed whole
      array and didn't found a duplicate of players[i].team */
            if (j == player_count) {
                uniques[*unique_count] = malloc((strlen(pit) + 1) * sizeof(char*));
                strcpy(uniques[*unique_count], pit);
                (*unique_count)++;
            }
        }
    }
    
    // get highest scoring team from teams array
    Team get_max(Team* teams, int team_count)
    {
    
        int max = 0;
        int maxIndex;
    
        for (int i = 0; i < team_count; i++) {
    
            int score = teams[i].score;
    
            if (score == 0) {
                break;
            }
    
            if (score > max) {
                max = score;
                maxIndex = i;
            }
        }
    
        return teams[maxIndex];
    }
    
    Team get_highest_team_score(Player* players, int player_count)
    {
    
        int i, j;
        int u_count = 0;
    
        char** names = malloc(TEAM_ALLOCATION * sizeof(char*));
    
        // get number of unique teams
        // and create dynamically allocated list
        // of names
        get_unique_teams(players, player_count, &u_count, names);
    
        // create array of Team structs
        // with the number of unique team names
        Team teams[u_count];
    
        for (i = 0; i < u_count; i++) {
    
            Team team;
            Team* t = &team;
    
            int total = 0;
            char* unique_team = names[i];
    
            for (j = 0; j < player_count; j++) {
    
                char* pjt = players[j].team;
    
                if (strcmp(unique_team, pjt) == 0) {
                    total += players[j].score;
                }
            }
    
            strcpy(t->team, unique_team);
            t->score = total;
    
            teams[i] = *t;
        }
    
        // release memory borrowed
        // to create uniq names list
        for (i = 0; i < u_count; i++) {
            free(names[i]);
        }
    
        free(names);
    
        Team max = get_max(teams, u_count);
        return max;
    }
    
    int main(void)
    {
    
        int team_count = 0;
        Player players[WORD_SIZE];
    
        char* path = "./teams.txt";
        char* text = get_file_content(path);
    
        split_text(text, players, &team_count);
    
        Player hs = get_highest_scorer(players, team_count);
        Team hst = get_highest_team_score(players, team_count);
    
        printf("%s, on team %s, had the highest score of %d\n", hs.full_name, hs.team, hs.score);
        printf("Team %s had the highest score with %d\n", hst.team, hst.score);
    
        free(text);
        return 0;
    }
    Last edited by catacombs; 06-25-2019 at 12:52 PM.

  8. #8
    Registered User
    Join Date
    Dec 2017
    Posts
    952
    Yikes! I meant something much simpler, like this:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    #define MAX_PLAYERS 500
    #define MAX_NAME    100
     
    typedef struct {
        char firstName[MAX_NAME];
        char lastName[MAX_NAME];
        int score;
        char team[MAX_NAME];
    } Player;
     
    int cmp_teams(const void *a, const void *b) {
        return strcmp(((Player*)a)->team, ((Player*)b)->team);
    }
     
    int main() {
        FILE *fin = fopen("teams.txt", "r");
        if (!fin) {
            perror("Cannot open input file");
            exit(EXIT_FAILURE);
        }
     
        Player players[MAX_PLAYERS];
     
        int n = 0;
        char line[1000];
        while (fgets(line, sizeof line, fin) != NULL) {
            Player p;
            if (sscanf(line, "%s %s %d %s", p.firstName,
                       p.lastName, &p.score, p.team) == 4) {
                if (n == MAX_PLAYERS) {
                    fprintf(stderr, "Player overflow\n");
                    exit(EXIT_FAILURE);
                }
                players[n++] = p;
            }
        }
     
        qsort(players, n, sizeof *players, cmp_teams);
     
        char max_team[MAX_NAME] = "", curr_team[MAX_NAME] = "";
        int  max_score = 0;
     
        int total = 0;
        for (int i = 0; i < n; ++i) {
            if (strcmp(players[i].team, curr_team) == 0)
                total += players[i].score;
            else {
                if (total > max_score) {
                    max_score = total;
                    strcpy(max_team, curr_team);
                }
                total = players[i].score;
                strcpy(curr_team, players[i].team);
            }
        }
     
        if (total > max_score) {
            max_score = total;
            strcpy(max_team, curr_team);
        }
     
        printf("%s %d\n", max_team, max_score);
     
        return 0;
    }
    Last edited by john.c; 06-25-2019 at 02:12 PM.
    If you want the truth to stand clear before you, never be for or against. - Sent-ts'an

  9. #9
    Registered User catacombs's Avatar
    Join Date
    May 2019
    Location
    /home/
    Posts
    81
    Definitely simpler! I guess my newbie tendencies got the best of me and went a little overboard.

  10. #10
    Registered User
    Join Date
    Apr 2019
    Posts
    662
    how have you got the maximum score of the players if you don't know how many players there are.

  11. #11
    Registered User catacombs's Avatar
    Join Date
    May 2019
    Location
    /home/
    Posts
    81
    Quote Originally Posted by cooper1200 View Post
    how have you got the maximum score of the players if you don't know how many players there are.
    If you're addressing this to me, I know how many because I counted the number of rows, each a player, from the input file.

  12. #12
    Registered User
    Join Date
    Apr 2019
    Posts
    662
    no sorry it was to the op should of said sorry

  13. #13
    Registered User catacombs's Avatar
    Join Date
    May 2019
    Location
    /home/
    Posts
    81
    No problem! I think OP said he or she won't know how many players will be in the final ahead of time. So, he or she will need to calculate that.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Mod c++ Volley ball teams
    By GrafixFairy in forum C++ Programming
    Replies: 0
    Last Post: 04-27-2014, 07:51 AM
  2. array for teams
    By Crossfire in forum C Programming
    Replies: 7
    Last Post: 04-14-2013, 01:30 PM
  3. Assigning teams
    By kenneykam in forum C Programming
    Replies: 3
    Last Post: 03-18-2013, 10:11 PM
  4. The last three teams
    By ivanovbg in forum C++ Programming
    Replies: 5
    Last Post: 10-04-2011, 11:33 AM

Tags for this Thread