natale
natale

Reputation: 1

Problems on computing statistics and parsing a text file

a must be simple question but I couldn't manage to do it.

I have to scan on a struct a text file with entries in this format: {"data1","data2",number1,number2}

And compute first populating a struct.

Text of the exercise: Consider the definition of the following structure

typedef struct {
char teamHome [30];
char teamHost [30];
int goalSquadraHome;
int goalSquadraOspite;
} match;

which is used to represent the result of a football match. Write a function that takes as parameters an array of games and its size e returns a result structure containing the following information: the number of games won by the home team, the number of games won by the visiting team, the number of ties, the name of the team that has scored the most goals in a match. Then write a program that, given the array containing all 380 Serie A 2019/2020 matches, print the information contained in the result.

The code is the following:

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

typedef struct{
        char squadraCasa[30];
        char squadraOspite[30];
        int golSquadraCasa;
        int golSquadraOspite;
} partita;

typedef struct {
        int partite_casa;
        int partite_ospite;
        int pareggi;
        char squad_magg_num_goal[30];
} risultato;

int main(){

FILE *fp;
risultato risultati;
int maxgoal = 0;
risultati.partite_casa = 0;
risultati.partite_ospite = 0;
risultati.pareggi = 0;
partita partite[380];
int i=0;
if((fp = fopen("partiteSerieA1920.txt","rt"))==NULL){
    printf("Errore nell'apertura del file\n");
    exit(1);
}
while(!feof(fp)){
      fscanf(fp,"{\"%s\",\"%s\",%d,%d",partite[i].squadraCasa,partite[i].squadraOspite,partite[i].golSquadraCasa,partite[i].golSquadraOspite);
      i++;
}
for(i=0;i<380;i++){
    if(partite[i].golSquadraCasa>partite[i].golSquadraOspite){
       risultati.partite_casa++;
    }else if(partite[i].golSquadraCasa<partite[i].golSquadraOspite){
       risultati.partite_ospite++;
    }else
       risultati.pareggi++;
    if(partite[i].golSquadraCasa>maxgoal){
       strncpy(partite[i].squadraCasa,risultati.squad_magg_num_goal,30);
       maxgoal = partite[i].golSquadraCasa;
    }
    if(partite[i].golSquadraOspite>maxgoal){
       strncpy(partite[i].squadraOspite, risultati.squad_magg_num_goal,30);
       maxgoal = partite[i].golSquadraOspite;  
    }
}
fclose(fp);
printf("%d %d %d %s\n",risultati.partite_casa,risultati.partite_ospite,&risultati.pareggi,&risultati.squad_magg_num_goal);
return 0;
}

Please let me know how to arrange it properly.

Upvotes: 0

Views: 46

Answers (2)

Evan Vrkljan
Evan Vrkljan

Reputation: 96

Give this a try, its a bit of a different approach:

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

typedef struct
{
    char squadraCasa[30];
    char squadraOspite[30];
    int golSquadraCasa;
    int golSquadraOspite;
} partita;

typedef struct
{
    int partite_casa;
    int partite_ospite;
    int pareggi;
    char squad_magg_num_goal[30];
} risultato;

// solves given problem and stores results in risultato struct
risultato *getResult(partita **playedGames, int size)
{
    risultato *result = malloc(sizeof(risultato));
    result->partite_casa = 0;
    result->partite_ospite = 0;
    result->pareggi = 0;

    int currentHighest = 0;

    for (int i = 0; i < size; i++)
    {
        if (playedGames[i]->golSquadraCasa > playedGames[i]->golSquadraOspite){
            result->partite_casa++;
            if(playedGames[i]->golSquadraCasa > currentHighest ){
                currentHighest = playedGames[i]->golSquadraCasa;
                strcpy(result->squad_magg_num_goal, playedGames[i]->squadraCasa);
            }
        }
        else if (playedGames[i]->golSquadraCasa < playedGames[i]->golSquadraOspite){
            result->partite_ospite++;
            if (playedGames[i]->golSquadraOspite > currentHighest){
                currentHighest = playedGames[i]->golSquadraOspite;
                strcpy(result->squad_magg_num_goal, playedGames[i]->squadraOspite);
            }
        }
        else{
            result->pareggi++;
        }
    }

    return result;
}

// This is a custom parser of a line from the file
// data = {"data1","data2",number1,number2}
// return -> partita struct
partita *newGame(char *data){

    partita *partite = malloc(sizeof(partita));
    char* temp;

    // Get Home Team
    temp = strchr(data, ',') -1;
    temp[0] = '\0';
    strcpy(partite->squadraCasa, data + 2);
    data = temp+1;


    // Get Away Team
    temp = strchr(data+1, ',') -1;
    temp[0] = '\0';
    strcpy(partite->squadraOspite, data + 2);
    data = temp + 1;

    // Get Home Score
    temp = strchr(data + 1, ',');
    temp[0] = '\0';
    partite->golSquadraCasa = atoi(data + 1);
    data = temp + 1;

    // Get Away Score
    temp = strchr(data, '}');
    temp[0] = '\0';
    partite->golSquadraOspite = atoi(data);

        // Return game
    return partite;
}

int main()
{

    FILE *fp;
    partita **partite = malloc(sizeof(partita *)); // list of size one, currently...
    risultato *risultati;
    char linea[50];
    int indice = 0;

    if ((fp = fopen("./partiteSerieA1920.txt", "rt")) == NULL)
    {
        printf("Errore nell'apertura del file\n");
        exit(1);
    }

    // For each linea in the file, load a game into an array.
    while (fgets(linea, 50,fp))
    {
        //chomp the \n
        linea[strlen(linea)-1]='\0';

        // increase size of list
        partite = realloc(partite, sizeof(partita *) * (indice + 1));

        // insert game into array of games
        partite[indice] = newGame(linea);

        indice++;
    }

    risultati = getResult(partite, indice);

    // Print risultato
    printf("\n----RESULT----\nHome Wins: %d\nAway Wins: %d\nTies: %d\nTeam With Most Goals: %s\n\n", risultati->partite_casa, risultati->partite_ospite, risultati->pareggi, risultati->squad_magg_num_goal);

    // free all allocated memory then return
    for (int i = 0; i < indice;i++){
        free(partite[i]);
    }
    free(partite);
    free(risultati);
    fclose(fp);
    return 0;
}

I was trying to run your code but couldnt get it to parse data from the file properly so i made a quick parser for you (This is in the code above already):

partita *newGame(char *data){

    partita *partite = malloc(sizeof(partita));
    char* temp;

    // Get Home Team
    temp = strchr(data, ',') -1;
    temp[0] = '\0';
    strcpy(partite->squadraCasa, data + 2);
    data = temp+1;


    // Get Away Team
    temp = strchr(data+1, ',') -1;
    temp[0] = '\0';
    strcpy(partite->squadraOspite, data + 2);
    data = temp + 1;

    // Get Home Score
    temp = strchr(data + 1, ',');
    temp[0] = '\0';
    partite->golSquadraCasa = atoi(data + 1);
    data = temp + 1;

    // Get Away Score
    temp = strchr(data, '}');
    temp[0] = '\0';
    partite->golSquadraOspite = atoi(data);

        // Return game
    return partite;
}

You can always try to use something similar to this to parse strings or lines that you bring in as I find it is more efficient to just code something that you know works to the specification you want.

Let me know if there is some problem with the code or would like to know more about the functionality of this. I tried to keep as much of this in Italian.

Cheers

Upvotes: 0

William Pursell
William Pursell

Reputation: 212248

There may be other issues, but certainly your flow control is wrong. Instead of the incorrect while/feof loop(Why is “while ( !feof (file) )” always wrong?), try something like:

partita *p = partite;
while( 4 == fscanf(fp, "{\"%29s\",\"%29s\",%d,%d",
        p->squadraCasa,
        p->squadraOspite,
        &p->golSquadraCasa,
        &p->golSquadraOspite
    ) ){ 
    p++;
}

Upvotes: 0

Related Questions