Visualizzazione dei risultati da 1 a 8 su 8
  1. #1
    Utente di HTML.it L'avatar di goatboy
    Registrato dal
    Mar 2011
    residenza
    Salerno
    Messaggi
    408

    [C] Problema stampa di una struttura dati

    Salve a tutti
    Ho questo codice che legge da file prima una stringa e poi un numero, fino al termine del file.
    Per poter leggere anche stringhe di più parole ho usato la fgets. So che si dovrebbe fermare al carattere di new line (quindi alla fine della riga di testo).
    codice:
        while(!feof(fp)) {
            fgets(studente->esamiSvolti[i], C, fp);
            fscanf(fp, "%d", &studente->votiEsami[i]);
            sommaVoti += studente->votiEsami[i];
            i++;
        }
    N.B. La variabile C vale 100.

    Quando vado a stampare, mi stampa una cosa così:
    codice:
    Esame: Esame1
    Voto: Voto1
    Esame:
    Voto: 0
    Esame: Esame2
    Voto: Voto2
    Esame: 
    Voto: 0
    Mi da degli spazi vuoti e dei voti zero.. credo che il problema sia nella fgets, ma magari mi sbaglio. Il programma non da errori. Qualcuno sa aiutarmi?

  2. #2
    Utente di HTML.it
    Registrato dal
    Jul 2008
    Messaggi
    1,326
    Dallo snippet di codice che hai postato è difficile capire quale sia il problema. Posta il necessario per poterlo comprendere (come sono dichiarati "studente", "esamiSvolti", "C" etc?). Sarebbe utile anche un esempio di contenuto del file che stai provando a leggere.
    every day above ground is a good one

  3. #3
    Utente di HTML.it L'avatar di goatboy
    Registrato dal
    Mar 2011
    residenza
    Salerno
    Messaggi
    408
    Questo è tutto il codice che riguarda l'apertura del file, la struttura dati e la stampa
    codice:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define R 30
    #define C 100
    #define L 20
    
    typedef struct {
        char nome[L];
        char cognome[L];
        char esamiSvolti[R][C];
        int votiEsami[R];
        int numeroEsami;
        float mediaEsami;
    } Studente;
    
    /* Funzione principale */
    int main(){
        Studente *studente;
        char nome[L], cognome[L], file[L];
        int i;
        
        // Alloco lo spazio in memoria
        studente = (Studente*)malloc(sizeof(Studente));
        
        // Acquisisco dati necessari per l'apertura del file..
    
    
        // Chiamo la funzione di lettura da file a cui passo la struttura dati
        leggiDaFile(file, studente);
        
        // Stampa
        printf("\nLo studente %s %s ha svolto i seguenti esami:\n", studente->nome, studente->cognome);
        for(i=0; i<studente->numeroEsami; i++) { // ciclo da 0 a numeroEsami
            printf("Esame: %sVoto: %d\n", studente->esamiSvolti[i], studente->votiEsami[i]);
        }
        // Stampa della media con 2 cifre decimali
        printf("La sua media e' di: %.2f\n\n", studente->mediaEsami);
    
    
        system("PAUSE");
        return 0;
    }
    
    
    void leggiDaFile(char file[], Studente *studente) {
        FILE *fp;
        int voto, sommaVoti=0, i=0, j;
        char esame[C];
        
        fp=fopen(file, "r");
        while(!feof(fp)) {
            fgets(studente->esamiSvolti[i], C, fp);
            fscanf(fp, "%d", &studente->votiEsami[i]);
            sommaVoti += studente->votiEsami[i];
            i++;
        }
        studente->numeroEsami = i;
        studente->mediaEsami = (float)sommaVoti/i;
        
        fclose(fp);
    }

  4. #4
    Utente di HTML.it
    Registrato dal
    Jul 2008
    Messaggi
    1,326
    Non hai postato un esempio del file che stai tentando di leggere, tuttavia dal tuo codice deduco che sia qualcosa del genere:

    codice:
    esame1
    voto1
    esame2
    voto2
    ...
    esameN
    votoN
    dove un esame è una stringa e un voto un intero.

    Se è così, puoi risolvere indicando esplicitamente alla fscanf() di leggere e scartare il carattere di newline subito dopo il numero:

    codice:
    fscanf(fp,"%d\n",&studente->votiEsami[i]);


    every day above ground is a good one

  5. #5
    Utente di HTML.it L'avatar di goatboy
    Registrato dal
    Mar 2011
    residenza
    Salerno
    Messaggi
    408
    Quote Originariamente inviata da YuYevon Visualizza il messaggio
    Puoi risolvere indicando esplicitamente alla fscanf() di leggere e scartare il carattere di newline subito dopo il numero:
    codice:
    fscanf(fp,"%d\n",&studente->votiEsami[i]);


    Ti ringrazio molto .. gli errori banali sono quelli peggiori

  6. #6
    Utente di HTML.it
    Registrato dal
    Jul 2008
    Messaggi
    1,326
    Quote Originariamente inviata da goatboy Visualizza il messaggio
    gli errori banali sono quelli peggiori
    Questo non è così banale come può sembrare. Le funzioni della famiglia *scanf() sono abbastanza "tricky", non a caso la man page relativa è piuttosto corposa. C'è chi suggerisce di evitare del tutto questa famiglia di funzioni per la lettura da file o da stdin e di ricorrere a work-around come leggere sempre il dato come stringa con la fgets() e poi convertirlo in intero con atoi(), ma per approfondimenti, nel caso ti interessi, ti rimando al web che se ne cade di articoli sull'argomento (si tratta comunque *quasi* esclusivamente di scuole di pensiero).
    every day above ground is a good one

  7. #7
    Utente di HTML.it L'avatar di goatboy
    Registrato dal
    Mar 2011
    residenza
    Salerno
    Messaggi
    408
    Quote Originariamente inviata da YuYevon Visualizza il messaggio
    Questo non è così banale come può sembrare. Le funzioni della famiglia *scanf() sono abbastanza "tricky", non a caso la man page relativa è piuttosto corposa. C'è chi suggerisce di evitare del tutto questa famiglia di funzioni per la lettura da file o da stdin e di ricorrere a work-around come leggere sempre il dato come stringa con la fgets() e poi convertirlo in intero con atoi(), ma per approfondimenti, nel caso ti interessi, ti rimando al web che se ne cade di articoli sull'argomento (si tratta comunque *quasi* esclusivamente di scuole di pensiero).
    Sapevo da tempo che la scanf() è da evitare per problemi legati ad un possibile overflow, però se utilizzata bene, con il dovuto controllo sul valore di ritorno e l'utilizzo del parametro [width] (es. %20s) non vedo che altri problemi possa generare. Più che altro è una funzione "limitante", visto che vincola il tipo di input da considerare.
    Ad ogni modo, per le stringhe ho sempre utilizzato la fgets(). Per i tipi numerici ho sempre utilizzato la scanf(), ma proverò a seguire il tuo consiglio. Grazie per la precisazione

  8. #8
    Utente di HTML.it
    Registrato dal
    Jul 2008
    Messaggi
    1,326
    Quote Originariamente inviata da goatboy Visualizza il messaggio
    proverò a seguire il tuo consiglio
    In realtà ti illustravo una scuola di pensiero più che un metodo da me adottato che ti consiglio. Personalmente mi sono sempre trovato sufficientemente bene con le funzioni della famiglia *scanf(), con gli adeguati accorgimenti e la dovuta lettura della documentazione.
    every day above ground is a good one

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.