[c] FILE, fgets, fread, fscanf

di il
12 risposte

[c] FILE, fgets, fread, fscanf

Buonasera,
devo scrivere un programma che legga e visualizzi il contenuto di un file ASCII, come per esempio eutoexec.bat.
Non ho problemi con la fgets, ho qualche problema con la fread, e ho tanti problemi con la scanf. Vado a copiare il codice e a commentarlo.

Il programma con fgets (soluzione non completamente mia) funziona bene:
 {//INIZIO PROGRAMMA
	char buffer[81];
	
	FILE *fp;
	fp=fopen("autoexec.txt", "r");
	
	if(fp==NULL) printf("Impossibile aprire file\n");
	else{//INIZIO ELSE PRINCIPALE
		printf("\nIl file autoexec.bat contiene: ");
		
		while(fgets(buffer, 80, fp) !=NULL)  
  		printf(buffer);
	
	}//FINE ELSE PRINCIPALE

	fclose(fp);
}//FINE PROGRAMMA
Il programma con fread non legge perfettamente. Non si blocca ma vengono stampati a monitor caratteri strani. Mi viene in mente quello che mi avete detto in un'altra occasione, ma vorrei conferma.
main()
{
	char buffer[81];
	int n;
	
	FILE *fp;
	fp=fopen("autoexec.txt", "r");
	
	if(fp==NULL) printf("Impossibile aprire file\n");
	else{//INIZIO ELSE PRINCIPALE
		printf("\nIl file autoexec.bat contiene: ");
		
		while(n=(fread(buffer,1,81,fp))) 
  		printf(buffer);

	}//FINE ELSE PRINCIPALE

	fclose(fp);
}//FINE PROGRAMMA
Il programma con fscan è un disastro totale: non solo il ciclo for è fuoriluogo (ma con il while tutte le condizioni di uscita non funzionavano), ma non capisco la sintassi fscanf(fp, "%c", buffer); Io mi sarei aspettato fscanf(fp, "%s", buffer); o al massimo utilizzando una variabile char Variabile; mi sarei aspettato fscanf(fp, "%c", &Variabile); ma niente di tutto questo funziona.
main()
{
	char buffer[81];
	int i;
	
	FILE *fp;
	fp=fopen("autoexec.txt", "r");
	
	if(fp==NULL) printf("Impossibile aprire file\n");
	else{//INIZIO ELSE PRINCIPALE   
		printf("\nIl file autoexec.bat contiene: ");
	
	for(i=0; i<1000; i++){	
		fscanf(fp, "%c", buffer);  //////////////////////////////////////////////
  		printf(buffer);
		}
	}//FINE ELSE PRINCIPALE

	fclose(fp);
Ho provato con eutoexec.bat e eutoexec.txt (giusto per provare) dove all'interno ho scritto con notepad dieci frasi per un totale di 700 caratteri circa.

Spero di essere stato chiaro.

Grazie.

12 Risposte

  • Re: [c] FILE, fgets, fread, fscanf

    La fgets con il format "%c" legge 1 carattere alla volta (default) senza fare alcun filtraggio: quindi legge spazi e caratteri di fine linea.
    La tua versione legge 1000 caratteri dal file e li mette tutti in buffer[0].
    Una versione più funzionale potrebbe essere questa:
    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
    	char buffer[81];
    	int i, e;
    	char c;
    
    	FILE *fp;
    	fp=fopen("autoexec.txt", "r");
    
    	if (fp==NULL) printf("Impossibile aprire file\n");
    	else{
    	// INIZIO ELSE PRINCIPALE
    		printf("\nIl file autoexec.bat contiene:\n");
    		while (!feof(fp)){
    	        	i = 0;
    			buffer[0]='\0';
    			do {
                    		e = fscanf(fp, "%c", &c);
                    		if (e == 1) {
                        			buffer[i] = c;
                        			i++;
                    		}
                		} while (c != '\n');
                		buffer[i] = '\0';
                		printf("%s", buffer);
      		}
        	}
    	fclose(fp);
    	return 0;
    }
    
    In pratica devi leggere 1 carattere alla volta e, tramite il contatore i devi posizionare il carattere all'interno di buffer. Se vuoi leggere una riga alla volta, quando trovi il carattere di fine riga devi terminare buffer e riprendere con i=0. Il test sulla fine del file (feof) ti dirà quando il file è finito.
  • Re: [c] FILE, fgets, fread, fscanf

    Soluzione interessantissima.
    Non mi era mai capitato una scanf o una fscanf che potesse essere assegnata.
    Ho intenzione di spendere del tempo per capire bene questa e = fscanf(fp, "%c", &c);

    Solo un ultima domanda. Mi era stato detto:
    Se usi file di testo e leggi/scrivi dati in Ascii allora usi fscanf/fprintf
    Se usi file binari allora usi fread/ferite
    fgets per cosa lo uso invece? Alla fine, mi sembra quella più comoda (in tanti casi).

    Grazie.
  • Re: [c] FILE, fgets, fread, fscanf

    Le funzioni fgets/fputs leggono/scrivono linee di testo di file ascii. Vedi la documentazione.

    Sono tutte funzioni e restituiscono qualcosa (come fa la fscanf). Leggi il valore restituito da ogni funzione dalla documentazione!
  • Re: [c] FILE, fgets, fread, fscanf

    Fgets si usa per ottenere intere righe di testo. Riempie una stringa di lunghezza conosciuta prendendo i caratteri da un file. a differenza di fscanf Essa può leggere solo stringhe e non si ferma allo spazio, Ma all'a capo. Mi sembra che a capo è costituito da 2 caratteri il primo dei quali E comunque preso nella stringa, ma non ricordo esattamente cosa faccia con il secondo ( poco male, al massimo si prova)
  • Re: [c] FILE, fgets, fread, fscanf

    Grazie a tutti.
    Sto veramente impazzendo con input ed output. Sto facendo tutti gli esercizi che posso...
    Adesso provo a migliorare anche quella fread che, come avevo scritto, non è che va benissimo.
    Appena posso leggo ciò che mi avete indicato.
    Provo una rabbia...
  • Re: [c] FILE, fgets, fread, fscanf

    oregon ha scritto:


    Le funzioni fgets/fputs leggono/scrivono linee di testo di file ascii. Vedi la documentazione.
    Sono tutte funzioni e restituiscono qualcosa (come fa la fscanf). Leggi il valore restituito da ogni funzione dalla documentazione!
    Credo che la chiave sia questa "restituiscono qualcosa" ma perché sui libri non trovo sempre n = fwrite?
    Lo capirò prima o poi, ma in questo momento provo rabbia, rabbia, rabbia!
    Devo leggere la documentazione!!!
  • Re: [c] FILE, fgets, fread, fscanf

    Perché non sempre serve il valore restituito. Importante è sapere che esiste e si puo6usare quando serve.
  • Re: [c] FILE, fgets, fread, fscanf

    oregon ha scritto:


    Perché non sempre serve il valore restituito. Importante è sapere che esiste e si puo6usare quando serve.
    Ok grazie.
  • Re: [c] FILE, fgets, fread, fscanf

    antragorn ha scritto:


    Non mi era mai capitato una scanf o una fscanf che potesse essere assegnata.
    Ho intenzione di spendere del tempo per capire bene questa e = fscanf(fp, "%c", &c);
    Se leggi la documentazione di fscanf (che è definita come int fscanf(FILE * stream, const char * format, ... );), vedrai che la funzione ritorna un valore che nel nostro caso ("%c") è il numero di caratteri letti (1) oppure -1 se c'è stato un problema. Sarebbe meglio usare la funzione int ferror(FILE * stream) per sapere se c'è stato un errore, ma anche il valore di ritorno può essere utile.
  • Re: [c] FILE, fgets, fread, fscanf

    Andrea Quaglia ha scritto:


    antragorn ha scritto:


    Non mi era mai capitato una scanf o una fscanf che potesse essere assegnata.
    Ho intenzione di spendere del tempo per capire bene questa e = fscanf(fp, "%c", &c);
    Se leggi la documentazione di fscanf (che è definita come int fscanf(FILE * stream, const char * format, ... );), vedrai che la funzione ritorna un valore che nel nostro caso ("%c") è il numero di caratteri letti (1) oppure -1 se c'è stato un problema. Sarebbe meglio usare la funzione int ferror(FILE * stream) per sapere se c'è stato un errore, ma anche il valore di ritorno può essere utile.
    Sì che n restituisse il numero di caratteri letti poi l'ho capito. Devo leggere la documentazione

    Nel frattempo ho migliorato quella fread che delle tre era l'ultima che non andava. buffer[] andava azzerato. Credo che non sia ottimale ma funziona. Il mio scopo è fare e capire tutti gli esercizi. A capire non ci siamo ancora, ma progressi ne ho fatti; adesso, perlomeno se ho un file di cui non conosco il contenuto (un file non creato da me per esempio), so utilizzare tutti e tre i modi per leggerlo: fgets, fscanf, e fread.
    Lo so, devo ancora studiare, leggere e ancora studiare!

    p.s. sono uno studente di Programmazione 1 e ci sto mettendo l'anima!!! Anche perché ho 46 anni e non mi interessa fregare la prof.ssa, ma imparare bene!!!
    //  PROGRAMMA con fread ///////////////////////////////////////////
    main()
    {
    	char buffer[100];
    	int n, i;
    
    	
    	
    	FILE *fp;
    	fp=fopen("autoexec.txt", "r");
    	
    	if(fp==NULL) printf("Impossibile aprire file\n");
    	else{//INIZIO ELSE PRINCIPALE
    		printf("\nIl file autoexec.bat contiene: ");
    	n=1;
    	while(n!=0){
    		n=fread(buffer, 1, 100,fp);
    			if(n==0) printf("\nContenuto letto con successo");
    			else
    			printf("%s", buffer);
    			for(i=0; i<100; i++)
    				buffer[i]='\0';
    			}
    			
    	}//FINE ELSE PRINCIPALE
    
    	fclose(fp);
    }//FINE PROGRAMMA
    ///////////////////////////////////////////////////////////////
    
  • Re: [c] FILE, fgets, fread, fscanf

    Un po' tardino per l'università ... anche se in realtà non è mai tardi se ci si mette passione e metodo ...
  • Re: [c] FILE, fgets, fread, fscanf

    oregon ha scritto:


    Un po' tardino per l'università ... anche se in realtà non è mai tardi se ci si mette passione e metodo ...
    Lo prendo come un augurio!!!
    Anzi adesso... sotto con il prossimo esercizio!

    Grazie di tutto!
Devi accedere o registrarti per scrivere nel forum
12 risposte