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;
}