Printf non stampa i valori

di il
23 risposte

23 Risposte - Pagina 2

  • Re: Printf non stampa i valori

    Considera questo:
    #include <stdio.h>
    #include <stdlib.h>
    #include <limits.h>
    
    int main() {
        void *p   = NULL;
        void *aux = NULL;
    
        p = calloc( 10, 4 ); // 10 elementi da quattro byte l'uno, per cominciare
    
        aux = realloc( p, ((size_t)-1) ); // sul mio PC, con 2GB di memoria, questa
                                          // fallisce; se il tuo computer ha molta
                                          // memoria potrebbe non fallire, rendendo
                                          // inefficace l'esempio
    
        if( aux == NULL ){
            // siccome realloc() e' fallita, aux e' NULL e p non e' cambiato
            // se vogliamo trattarlo come un errore, e' bene deallocare la memoria
            // allocata in p, per non lasciare "cadaveri" in giro! :)
            free( p );
            p = NULL;
            // in questo esempio andiamo avanti lo stesso; normalmente
            // restituiresti un codice d'errore, o qualcosa del genere
        }
        else {
            p = aux;  // il puntatore restituito da realloc() potrebbe
                      // essere diverso da quello passato in p
        }
    
        if( p != NULL ) free( p ); // torniamo alle condizioni iniziali
        p = calloc( 10, 4 ); // 10 elementi da quattro byte l'uno, per cominciare
    
        aux = realloc( p, 4*250000000 ); // questa dovrebbe riuscire, ma la
                                         // richiesta e' piuttosto elevata, quindi
                                         // probabilmente ti verra' restituito un
                                         // puntatore diverso da p
    
        if( aux == NULL ){
            // se realloc() fosse fallita, aux sarebbe NULL e p non sarebbe cambiato
            // volendo trattarlo come un errore, sarebbe bene deallocare la memoria
            // allocata in p, per non lasciare "cadaveri" in giro! :)
            free( p );
            p = NULL;
            // in questo esempio andiamo avanti lo stesso; normalmente
            // restituiresti un codice d'errore, o qualcosa del genere
        }
        else {
            p = aux;  // il puntatore restituito da realloc() e' probabile
                      // che sia diverso da quello passato in p
        }
    
        if( p != NULL ) free( p );
    
        return 0;
    }
  • Re: Printf non stampa i valori

    Grazie mille!
  • Re: Printf non stampa i valori

    Se ti son stato utile, son contento. Poi facci sapere com'è andata col resto dell'esercizio.
  • Re: Printf non stampa i valori

    Ciao, si sei stato molto utile.
    Ho ragionato sull'uso di realloc, ma mi sono sorti dei dubbi.
    Io so a priori la quantità di dati, in questo caso sono 10, di cui, il primo (il famoso numero 13) non mi interessa, e inizio a contare da zero, quindi il totale è 8.
    Il mio ragionamento è corretto?
    Se gli do un valore inferiore, me li stampa comunque tutti a video, io mi aspettavo un troncamento.

    
     dati *leggi_file(FILE *fp,int *n_letti) {
    
       int i=0, j=0;
       char riga[RIGA];
       char *tmp;
       *n_letti=0;
       
       dati *vet=(dati*)malloc(8*sizeof(dati));
       
       
          while((tmp=fgets(riga,sizeof(riga),fp))!=NULL){
             sscanf(riga,"%d %d %c %d ",&vet[j].id,&vet[j].n_tuffo,&vet[j].id_giudice,&vet[j].voto);
             j++;
          }
        
       *n_letti=j;
    
       return vet;   
    }
    
  • Re: Printf non stampa i valori

    Mmm... Se hai dieci righe nel file e scarti la prima te ne ritrovi nove, non otto. Nove, che poi conti con indici "zero based", ovvero 0, 1, 2, 3, 4, 5, 6, 7 e 8. Dunque dovrai allocare spazio per nove strutture dati, non per otto.

    Il fatto che non ottieni troncamenti dipende dal tipo di controllo che hai imposto al flusso delle operazioni: da come hai impostato il while, in ogni caso leggerai righe dal file fintanto che... ci sono righe nel file! Tra l'altro, se allochi spazio per otto righe e poi ne leggi nove finisci per avere degli "sbordamenti", con effetti imprevedibili e possibilmente nefasti (un bell'impallamento del programma).

    Visto che la prima riga del file NON contiene la quantità delle righe, secondo me ti conviene verificare quella quantità PRIMA di allocare la memoria (ma questa è un'opinione che deriva da un mio personale modo di fare, efficiente o inefficiente che sia). Verificata la quantità delle righe e allocata la memoria necessaria, è abbastanza irrilevante il metodo che usi per interrompere il ciclo, ovvero è irrilevante se interrompi quando non hai più righe nel file o quando raggiungi il valore che hai riscontrato contando le righe stesse nel passaggio precedente.

    Da non dimenticare: se fai la lettura "preventiva" devi ricordarti di riportare il segnaposto del file nella sua posizione iniziale (magari con rewind()?) prima di iniziare il caricamento vero e proprio dei dati.
  • Re: Printf non stampa i valori

    Scusami, potresti spiegare meglio il concetto di "interrompere il ciclo" e anche di questa parte "Da non dimenticare: se fai la lettura "preventiva" devi ricordarti di riportare il segnaposto del file nella sua posizione iniziale (magari con rewind()?) prima di iniziare il caricamento vero e proprio dei dati."
    Anche un mini esempio andrebbe bene.
    Ho letto della documentazione su internet ma ammetto di aver qualche difficoltà a mettere giù il codice.
  • Re: Printf non stampa i valori

    Con "interrompere il ciclo" intendo che puoi uscire dal tuo for o perché hai impostato un contatore (nel qual caso esci quando raggiungi il massimo previsto) o perché leggendo dal file hai incontrato EOF. Se conosci a priori la quantità delle righe da leggere è equivalente, al netto di errori nella lettura dovuti a chissà cosa.

    Per il resto, quando analizzi il contenuto del file per verificare quante righe ci sono ne scorri il contenuto dall'inizio alla fine. Quando sei in fondo alla verifica sei in fondo anche al file, per cui non puoi più leggere niente -- per questo, prima di poter caricare i dati sei costretta a tornare "da capo". Per farlo ci sono più metodi, il più sbrigativo dei quali è la funzione standard rewind(), che riporta il segnaposizione dello stream a zero. Dopo aver chiamato rewind() ti trovi praticamente nella stessa condizione nella quale ti trovavi subito dopo aver aperto il file con fopen(), e puoi ricominciare a leggere i dati per caricarli nelle tue strutture.
  • Re: Printf non stampa i valori

    Ad esempio, questa funzione conta la quantità delle righe presenti in un file già aperto con fopen in modalità "r". In uscita, il segnaposizione dello stream si trova dove si trovava al momento della chiamata (a meno che si siano verificati errori in fsetpos()).
    #include <stdio.h>
    #include <stdlib.h>
    
    enum {
        err_NoErr,
        err_NullPtr,
        err_NoPos,
        err_NoReset
    };
    
    /*==============================================================================
    Rileva la quantita' delle righe presenti nel contenuto d'un file.
    Se il rilevamento ha successo, la quantita' delle righe viene collocata in *qr.
    Se il rilevamento fallisce, *qr non viene modificato. In caso di fallimento, la
    funzione puo' restituire err_NullPtr o err_NoPos o err_NoReset. In caso di
    successo restituisce sempre err_NoErr.
    ==============================================================================*/
    
    int quantita_righe_nel_file( FILE *f, size_t *qr ) {
        int errore = err_NullPtr;
    
        if( f!=NULL && qr!=NULL ) {
            fpos_t ex_pos;
            size_t qrTmp;
            int c;
            
            // rileva la posizione corrente nel file
            errore = fgetpos( f, &ex_pos );
            if( errore ) return err_NoPos;
    
            rewind( f ); // "riavvolge" il file per essere
                         // sicuri di rilevare TUTTE le righe
    
            // ricava la quantita' delle righe nel file
            for( qrTmp=1, c=fgetc(f); c!=EOF; c=fgetc(f) )
                qrTmp += c=='\n';
    
            // ripristina la posizione nel file
            errore = fsetpos( f, &ex_pos );
            if( errore ) return err_NoReset;
    
            *qr = qrTmp;
            errore = err_NoErr;
        }
    
        return errore;
    }
  • Re: Printf non stampa i valori

    Ciao!
    Scusami se rispondo solo adesso.
    Ho provato a fare un altro esercizio col codice che mi consigli.
    Ti invio sia il testo che il codice.
    Grazie mille per tutta questa disponibilità.

    Gli organizzatori di una maratona podistica utilizzano un ?le di testo per memorizzare le informazioni relative alle prestazioni dei concorrenti. I concorrenti partono scaglionati, e la classi?ca ?nale viene determinata dal tempo complessivo impiegato da ciascun concorrente per terminare il percorso. La prima riga del ?le contiene il numero dei concorrenti. Tutte le altre righe contengono l’orario di partenza oppure di arrivo di ciascun concorrente. Piu` precisamente, ciascuna riga (tranne la prima) contiene le seguenti informazioni, codi?cate come campi separati da caratteri di spaziatura. I campi sono: • numero progressivo che identi?ca il concorrente (massimo quattro cifre); • genere del concorrente (un singolo carattere: M per maschile, F per femminile); • et`a del concorrente; • orario, nel formato ‘hh:mm:ss’; • un singolo carattere che indica se l’orario si riferisce alla partenza (P) o all’arrivo (A) del concorrente. La lunghezza di ciascuna riga non pu`o superare i 30 caratteri e l’ordine delle righe `e completamente arbitrario. Pu`o accadere che un concorrente si ritiri prima del termine della gara. In tal caso il ?le conterr`a soltanto una riga relativa all’orario di partenza e non ci sar`a alcuna riga con l’orario di arrivo. Ad esempio, un ?le di questo tipo potrebbe iniziare con le seguenti righe:
    72 1030 M 46 14:37:10 P 1007 F 40 14:08:31 P 1027 M 25 14:32:37 P 1058 F 23 18:25:37 A 1030 M 46 17:03:03 A 1034 M 22 14:42:40 P ...
    Si scriva un programma in linguaggio C che, dato il nome del ?le come argomento dalla riga di comando, ne legga il contenuto e che calcoli:
    1. il numero identi?cativo del concorrente piu` anziano che `e giunto al traguardo;
    2. l’et`a media di tutti i concorrenti che sono partiti;
    3. il tempo di percorrenza medio degli uomini e delle donne che sono giunti al traguardo, espresso in minuti;
    4. la classi?ca ?nale (numero identi?cativo e tempo di percorrenza in minuti) dei concorrenti che hanno completato la gara, ordinati per tempo di percorrenza decrescente.
    Si ricorda che la funzione scanf (e varianti) accetta la speci?ca di delimitatori che non siano caratteri di spaziatura (ad esempio, si pu`o speci?care il formato "%d:%d:%d" per leggere gli orari).


    Dati :
    
    83
    1023 F 46 14:29:39 P
    1081 F 73 15:49:42 P
    1013 M 33 14:17:32 P
    1079 M 52 15:47:25 P
    1070 M 24 18:17:31 A
    1038 M 29 14:48:59 P
    1068 F 23 15:31:54 P
    1050 M 27 15:08:52 P
    1030 M 26 14:38:13 P
    1077 F 29 19:49:37 A
    1031 F 41 14:39:37 P
    1044 F 25 18:04:40 A
    1074 F 31 18:18:54 A
    1057 M 86 19:14:51 A
    1019 F 25 14:24:00 P
    1039 M 27 17:34:01 A
    1042 F 35 14:55:03 P
    1077 F 29 15:44:46 P
    1025 M 58 14:31:51 P
    1049 F 38 15:07:39 P
    1047 F 76 15:04:10 P
    1071 M 21 18:12:48 A
    1005 M 43 14:09:07 P
    1027 M 26 14:34:35 P
    1059 F 64 15:19:27 P
    1021 F 39 14:26:07 P
    1041 M 18 18:19:18 A
    1062 F 31 15:23:51 P
    1022 F 66 14:27:47 P
    1008 F 32 14:12:34 P
    1011 F 32 16:48:32 A
    1066 M 28 15:28:22 P
    1076 F 46 17:48:40 A
    1044 F 25 14:58:23 P
    1040 M 25 14:51:56 P
    1003 F 35 14:06:04 P
    1029 F 20 14:37:29 P
    1045 M 36 18:56:00 A
    1037 M 64 14:47:02 P
    1042 F 35 18:58:40 A
    1031 F 41 17:26:08 A
    1064 F 21 18:07:36 A
    1062 F 31 19:09:15 A
    1008 F 32 17:43:37 A
    1026 M 57 14:32:58 P
    1067 M 46 19:27:27 A
    1078 F 24 15:45:57 P
    1065 M 52 15:27:35 P
    1017 F 27 16:40:29 A
    1075 M 30 19:33:29 A
    1003 F 35 17:36:55 A
    1075 M 30 15:42:19 P
    1054 M 35 17:26:17 A
    1028 F 33 14:35:39 P
    1009 F 26 14:13:13 P
    1069 M 48 15:32:49 P
    1011 F 32 14:15:52 P
    1073 M 25 18:03:33 A
    1045 M 36 15:00:13 P
    1016 M 24 17:35:02 A
    1067 M 46 15:30:12 P
    1043 M 23 14:56:45 P
    1001 F 65 14:03:01 P
    1061 M 18 15:22:02 P
    1063 M 20 19:23:03 A
    1052 M 19 17:39:33 A
    1082 M 34 15:50:25 P
    1071 M 21 15:36:10 P
    1043 M 23 17:17:36 A
    1074 F 31 15:40:32 P
    1018 M 79 14:23:00 P
    1049 F 38 17:10:36 A
    1032 M 40 14:41:06 P
    1000 M 38 16:12:39 A
    1017 F 27 14:21:22 P
    1015 M 51 14:20:15 P
    1048 M 48 15:06:10 P
    1068 F 23 17:54:44 A
    1033 F 18 14:42:17 P
    1060 M 44 15:21:10 P
    1070 M 24 15:34:10 P
    1078 F 24 18:02:00 A
    1080 F 31 15:49:12 P
    1026 M 57 17:44:57 A
    1036 F 52 14:45:56 P
    1033 F 18 16:56:00 A
    1005 M 43 16:16:48 A
    1000 M 38 14:01:27 P
    1022 F 66 17:29:43 A
    1021 F 39 16:28:54 A
    1072 F 18 15:37:40 P
    1016 M 24 14:20:46 P
    1007 M 32 14:11:45 P
    1058 M 42 15:17:44 P
    1020 M 58 14:25:21 P
    1029 F 20 16:37:32 A
    1001 F 65 17:22:14 A
    1050 M 27 19:05:27 A
    1046 M 24 17:21:38 A
    1039 M 27 14:50:46 P
    1057 M 86 15:17:05 P
    1065 M 52 19:03:16 A
    1040 M 25 18:30:06 A
    1051 M 33 15:10:30 P
    1010 M 30 14:14:23 P
    1076 F 46 15:43:04 P
    1064 F 21 15:25:35 P
    1063 M 20 15:24:51 P
    1053 M 26 15:12:12 P
    1007 M 32 17:07:42 A
    1012 F 62 17:46:26 A
    1035 M 22 14:44:18 P
    1055 M 21 15:14:26 P
    1055 M 21 18:20:59 A
    1034 F 72 14:43:22 P
    1014 F 29 14:19:29 P
    1009 F 26 18:18:13 A
    1054 M 35 15:12:50 P
    1061 M 18 17:39:34 A
    1004 M 64 14:07:14 P
    1024 M 21 14:30:46 P
    1002 F 65 16:55:45 A
    1006 F 50 14:10:42 P
    1056 F 23 15:16:08 P
    1024 M 21 17:33:15 A
    1036 F 52 17:54:15 A
    1012 F 62 14:16:48 P
    1066 M 28 19:21:17 A
    1073 M 25 15:39:20 P
    1025 M 58 18:05:55 A
    1046 M 24 15:02:13 P
    1004 M 64 17:08:17 A
    1041 M 18 14:53:35 P
    1056 F 23 17:27:21 A
    1052 M 19 15:11:16 P
    1002 F 65 14:04:45 P
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #include <string.h>
    
    #define BUF 128
    #define RIGA 50
    #define MAX 30
    
    typedef struct{
        int numero_partecipanti;
        int id;
        char sesso;
        int eta;
        int ora;
        int minuti;
        int secondi;
        char stato;
     
    }dati;
    
    FILE * aprifile(char * nome_file, char * modalita);
    dati *quantita_righe_nel_file( FILE *fp, size_t *qr );
    void stampa_letti(dati * vet,int n);
    
    
    
    
    
    int main(int argc, char **argv){
        
        if(argc!=2){
            puts("inserire 2 argomenti per procedere\n");
            exit(-1);
        }
        
        int numero_letti;
    		FILE *fp=aprifile(argv[1],"r");
    		dati *quantita_righe_nel_file( FILE *fp, size_t *qr );
    	
    	int i;
    	/*	for(i=0; i<numero_letti; i++){
          if(numero[i].id!=0){
    		printf("%d \n", numero[i].id);
          }	  
        } */
    	    
    	return 0;
    }
    
    FILE * aprifile(char * nome_file, char * modalita){
        FILE * fp=fopen(nome_file,modalita);
    		if(fp==NULL){
    			fprintf(stderr,"impossibile aprire il file %s in modalita %s",nome_file,modalita);
    			exit(-1);
    		}
        return fp;
    }
    
    dati *quantita_righe_nel_file( FILE *fp, size_t *n_letti ) {
    		enum {
        err_NoErr,
        err_NullPtr,
        err_NoPos,
        err_NoReset
    };
        int errore = err_NullPtr;
    
        if( fp!=NULL && n_letti!=NULL ) {
            fpos_t ex_pos;
            size_t qrTmp;
            int c;
            
         
            errore = fgetpos( fp, &ex_pos );
            if( errore ) return err_NoPos;
    
            rewind( fp );
            for( qrTmp=1, c=fgetc(fp); c!=EOF; c=fgetc(fp) )
                qrTmp += c=='\n';
    
           
            errore = fsetpos( fp, &ex_pos );
            if( errore ) return err_NoReset;
    
            *n_letti = qrTmp;
            errore = err_NoErr;
        }
    
        return errore;
    }
    		
    
    
    
    
    void stampa_letti(dati *vet,int n){
        int i,j;
        
    		for(i=0;i<1;i++){
    			printf("%d \n",vet[i].numero_partecipanti);
    		}
    		for(j=0;j<n;j++){
    			if(vet[j].id!=0){
    			printf("%d %c %d %d:%d:%d %c\n",vet[j].id,vet[j].sesso,vet[j].eta,vet[j].ora,vet[j].minuti,vet[j].secondi,vet[j].stato);
            }
        }
    }
    
Devi accedere o registrarti per scrivere nel forum
23 risposte