Domanda Esercizi in C da svolgere

Slat3

Utente Palladium
16 Maggio 2013
2,359
214
4,480
1,793
Ultima modifica:
Salve, questo qui è un esercizio da svolgere in C:

Codice:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#define LUNGHEZZA_STRINGA    64
#define NUMERO_SQUADRE 10

//
//
// Scrivere un programma che permette di gestire la classifica di un torneo
// di pallavolo
//
// L'elenco delle squadre è memorizzato in un archivio implementato come vettore
// di strutture, ogni struttura contiene il nome della squadra, il punteggio, il
// numero di partite fatte e la differenza set (vinti - persi).
//
// Implementare un applicazione che permette:
//    1. caricare i dati da file
//    2. salvare i dati su file
//    3. inserire un nuovo risultato
//    4. ordinare rispetto al punteggio, in caso di parita' vale il minor numero di partite,
//        in caso di ulteriore parita' la differenza set
//    5. stampa
//    6. inserire una squadra nell'archivio

typedef struct squadra_s {
    char nome[LUNGHEZZA_STRINGA];
    int punteggio;
    int numero_partite;
    int differenza_set;
} squadra_t;

// Secondo tipo
typedef squadra_t classifica_t[NUMERO_SQUADRE];

void ordina(classifica_t c) {
    // Da implementare: calcola la classifica come indicato nel commento
    // introduttivo
}

int carica(classifica_t c, const char* nome_file) {
    // Nota che per caricare il vettore uso un file binario,
    // ripassa la gestione dei file binari
    FILE* fp = NULL;
    fp = fopen(nome_file, "rb");
    if (fp == NULL)
        return 0;
    if (fread(c, sizeof(squadra_t), NUMERO_SQUADRE, fp) != NUMERO_SQUADRE)
        return 0;
    return 1;
}

int salva(classifica_t c, const char* nome_file) {
    // Nota che per salvare il vettore uso un file binario,
    // ripassa la gestione dei file binari
    FILE* fp = NULL;
    fp = fopen(nome_file, "wb");
    if (fp == NULL)
        return 0;
    if (fwrite(c, sizeof(squadra_t), NUMERO_SQUADRE, fp) != NUMERO_SQUADRE)
        return 0;
    return 1;
}

int inserisci_squadra(classifica_t c, const char* nome_squadra) {
    // I dati vengono inseriti nella prima casella vuota, una casella e' vuota
    // quando il campo nome della squadra e' uguale a ""
    for (int i = 0; i < NUMERO_SQUADRE; ++i) {
        // Verifica se la casella e' vuota, qualora lo fosse viene copiata
        // il nome della squadra ed inizializzati a zero tutti gli altri valori
    }
}

int aggiorna_calendario(classifica_t c, const char* squadra_1, const char* squadra_2, int set_1, int set_2) {
    // in base al numero di set stabilisce qual'e' la squadra vincente
    // cerca la prima squadra e aggiorna i valori in base al risultato
    // cerca la seconda squadra e aggiorma i valori in vase al risultato
}
int main(void) {
    classifica_t classifica = { {"", 0, 0, 0} }; // Inizializzazione del vettore, puo' essere fatto anche usando un ciclo
    int scelta;
    do {
        printf("1. Carica\n");
        printf("2. Salva\n");
        printf("3. Inserisci un nuovo risultato\n");
        printf("4. ordina\n");
        printf("5. stampa\n");
        printf("6. inserisci una squadra nuova\n");

        printf("0. esci\n");
        printf(">> ");
        scanf("%d", &scelta);
        switch (scelta) {
        case 0:
            break;
        case 1:
            break;
        case 2:
            break;
        case 3:
            break;
        case 4:
            break;
        case 5:
            break;
        case 6:
            break;
        }
    } while (scelta != 0);

}

Qualcuno potrebbe aiutarmi con i vari passaggi? Non chiedo il codice pronto ma magari un piccolo aiuto, in particolar modo in "
L'elenco delle squadre è memorizzato in un archivio implementato come vettore (quindi typedef struct in generale)
// di strutture" e con le funzioni?
Anche perchè non ho ben capito come funziona la differenza set etc per come è impostato il programma
 
Ultima modifica:
L'elenco delle squadre è memorizzato in un archivio implementato come vettore (quindi typedef struct in generale) di strutture" e con le funzioni?
Questa parte l'hai già fatta. Non so se l'hai scritta tu o se era parte inclusa nel testo, ma è corretta. Devi solo implementare le varie funzioni e riempire lo switch-case nel main.

Salva e carica sono già implementate (da te?), ma usano una convenzione un po' strana per il C: return 1 vuol dire corretto e return 0 vuol dire sbagliato. Io le avrei implementate al contrario, così:
C:
int carica(classifica_t c, const char* nome_file) {
    FILE* fp = NULL;
    fp = fopen(nome_file, "rb");
    return !fp || fread(c, sizeof(squadra_t), NUMERO_SQUADRE, fp) != NUMERO_SQUADRE;
}

int salva(classifica_t c, const char* nome_file) {
    FILE* fp = NULL;
    fp = fopen(nome_file, "wb");
    return !fp || fwrite(c, sizeof(squadra_t), NUMERO_SQUADRE, fp) != NUMERO_SQUADRE;
}

Inserisci squadra lo puoi implementare in questo modo:
C:
int inserisci_squadra(classifica_t c, const char* nome_squadra) {
    // I dati vengono inseriti nella prima casella vuota, una casella e' vuota
    // quando il campo nome della squadra e' uguale a ""
    for (int i = 0; i < NUMERO_SQUADRE; ++i) {
        // Verifica se la casella e' vuota, qualora lo fosse viene copiata
        // il nome della squadra ed inizializzati a zero tutti gli altri valori
        if (c[i].nome[0] == '\0') {
            strcpy(c[i].nome, nome_squadra);
            c[i].punteggio = 0;
            c[i].numero_partite = 0;
            c[i].differenza_set = 0;
            return 0; // squadra inserita correttamente
        }
    }
    return 1; // errore, il vettore è pieno
}
E nel main devi scrivere cose di di questo tipo:
C:
char squadra[LUNGHEZZA_STRINGA];
// ...
case 0:                                                         
    if (carica(classifica, "classifica.sav")) // oppure !carica, dipende da come lo implementi                 
        printf("Il file classiica.sav non è stato caricato correttamente\n");
    break;                                                      
case 1:                                                         
    // qui devi fare qualcosa di quasi uguale a quello che ho fatto nel case 0
    break;
// ...                                                    
case 6:                                                         
    printf("Inserisci il nome della squadra che vuoi inserire: ");
    scanf("%s", squadra);                                       
    if (inserisci_squadra(classifica, squadra))                
        printf("Impossibile aggiungere ulteriori squadre\n");   
    break;
// ...

Prova ad implementare qualche altro pezzo e poi ne discutiamo.
 
Ultima modifica:
case 0:
if (carica(classifica, "classifica.sav")) // oppure !carica, dipende da come lo implementi
printf("Il file classiica.sav non è stato caricato correttamente\n");
break;

Perchè qui non è caricato correttamente?

case 1:
// qui devi fare qualcosa di quasi uguale a quello che ho fatto nel case 0
break;
// ...
case 6:
printf("Inserisci il nome della squadra che vuoi inserire: ");
scanf("%s", squadra);
if (inserisci_squadra(classifica, squadra))
printf("Impossibile aggiungere ulteriori squadre\n");
break;

// ...
[/code]

Prova ad implementare qualche altro pezzo e poi ne discutiamo.

Cosa fa quell'if? Cioè, if inserisci squadra, cosa?

Non ho capito come implementare le funzioni richieste, altrimenti lo avrei scritto di già (disconoscendo tra l'altro la classifica di pallavolo)
 
In C zero è false e non-zero è true. Quindi quando hai una condizione del tipo:
C:
int pippo() { /* blah blah */ }
if (pippo()) do_something();
equivale a:
C:
int pippo() { /* blah blah */ }
if (pippo() != 0) do_something();

Quindi if (carica(classifica, "classifica.sav")) equivale a if (carica(classifica, "classifica.sav") != 0) e if (inserisci_squadra(classifica, squadra)) equivale a if (inserisci_squadra(classifica, squadra) != 0). Usa la sintassi che ritieni più chiara.

Praticamente sto dicendo che quelle funzioni restituiscono 0 quando tutto fila liscio e qualcos'altro quando c'è un errore. La funzione carica che c'era già scritta in realtà funziona al contrario: 1 quando fila liscio e 0 quando c'è un errore.

Non ho capito come implementare le funzioni richieste, altrimenti lo avrei scritto di già (disconoscendo tra l'altro la classifica di pallavolo)
Non ho capito cosa non hai capito. Implementare le funzioni e inserirle dentro lo switch-case è la richiesta dell'esercizio, ma io non capisco in che punto ti blocchi. Per scorrere i vari elementi del vettore puoi prendere spunto dalla funzione inserisci_squadra che ti ho scritto. Prendi quella che ti sembra più facile tra le due funzioni rimanenti (ordina e aggiorna_calendario) e prova a spiegarmi dove ti blocchi. Il codice di partenza l'hai compreso pienamente o c'è qualche pezzo che non ti è ancora chiaro? Il codice di inserisci_squadra che ti ho scritto l'hai capito?