Visualizzazione dei risultati da 1 a 8 su 8
  1. #1

    [ANSIC] Scrittura/lettura su/da file

    Ciao a tutti!

    Sto cercando di capire come utilizzare le funzioni di C per la scrittura su file...
    Posseggo il manuale, ma non riesco lo stesso a risolvere questo che dovrebbe essere un problema facile:

    /* Sia dato un file di testo, "Ingresso.txt", contenente un elenco di numeri
    * reali. Il file contiene un numero reale per ciascuna linea di testo.
    * Creare un file di testo "Uscita.txt" contenente la frase
    * "Il file di origine contiene N numeri aventi somma S"
    * dove N è il numero di elementi (numeri reali) contenuti nel file di origine
    * ed S è la somma di tali numeri.
    * Il programma deve emettere un messaggio di errore in caso di errore di
    * apertura o di chiusura dei file.
    */

    Penso di non aver capito bene cosa passare alle funzioni.
    Inoltre tutto quello che riesco a scrivere su file sono quadratini (il programma C dice che la variabile contiene un "f", ma sul file appare un quadratino)

    Qualcuno è così gentile e paziente da aiutarmi a risolvere questo programma?

    Grazie gia da ora
    Saluti!

  2. #2
    Utente di HTML.it L'avatar di infinitejustice
    Registrato dal
    Nov 2001
    residenza
    Barcelona
    Messaggi
    772
    Una cosa cosi... ho messo i commenti quindi nn dovresti aver problemi.

    void main(){

    FILE *in, *out;
    char line[100];
    double value = 0, sum = 0;
    int nrLines = 0;

    if(!(in = fopen("ingresso.txt", "r"))){
    printf("Impossibile aprire il file di input. Bye");
    exit (-1);
    }

    if(!(out = fopen("uscita.txt", "w+"))){
    printf("Impossibile creare il file di output. Bye");
    exit (-1);
    }

    while(!(feof(in))){ //scorre il file fino alla fine
    fgets(line, 100, in); //prelevo una linea (max 100 caratteri) dall'input
    value = atof(line); //estraggo il valore reale contenuto nella linea
    sum += value; //faccio la somma dei valori che di volta in ovlt estraggo
    nrLines++; //aggiorno il numero di linee presenti nel file
    }

    fprintf(out, "Il file di origine contiene %d numeri aventi somma %f", nrLines, sum);

    fclose(in);
    fclose(out);
    }
    Live fast. Troll hard.
    Pythonist | Djangonaut | Puppeteer | DevOps | OpenStacker | Lost in malloc
    Team Lead @Gameloft Barcelona

  3. #3

    Mitico!

    Grande!

    Grazie 1000!!! Ho capito un sacco di cose, grazie al tuo esempio.
    Usavo le funzioni sbagliate (in effetti feof è utilissima)

    C'è solo un piccolo problema:
    Nel file ingresso metto i valori
    3.4
    7.8
    102.87
    12.56
    11.11
    666.666

    E il programma restituisce come somma:
    13760160.000000

    Dove sbaglio?

    Grazie ancora!

  4. #4

    Problema risolto...

    Non facevo l'include della stdlib.h per il corretto utilizzo della funzione atof(). Strano che il compilatore non abbia segnalato nessun warning...

    Byez

  5. #5

    problema ricomplicato, risolto, ma non in maniera ottimale

    Ciao!

    Ho provato a modificare il programma facendo in modo che possa acquisire anche numeri dall'utente. Questi vengono memorizzati nel file ingresso.txt e suddivisi da un return ("\n"). Il problema ora è che feof() legge una volta di troppo i valori (perchè scandaglia anche la nuova riga vuota), segnala una riga in più di quella che dovrebbe esserci e, stranamente, somma due volte l'ultimo valore (mi sfugge il perchè). Ho ovviato a questo inconveniente facendo:

    codice:
    nrLines--;
    sum -= value;
    Esiste una soluzione più elegante?
    Qualcuno può spiegarmi il perchè dell'aggiunta dell'ultimo valore?

    Grazie!

    Segue il sorgente completo

    codice:
    #include <stdio.h>
    #include <stddef.h>
    #include <stdlib.h>
    
    #define MAX 20
    #define FILE_INPUT "ingresso.txt"
    #define FILE_OUTPUT "uscita.txt"
    
    int main(){
        
        //variabili
        int choose = 0;
        
        //Prototipi
        void scriviRis(void);
        void addNumbers(void);
        void deleteNumbers(void);
        
        while(choose < 3){
                     
             puts("Che cosa si desidera fare?");
             puts("1) Inserire numeri sul file");
             puts("2) Scrivere la somma dei numeri sul file");
             puts("Premere un qualunque altro tasto per uscire dal programma");
             puts("-------");
             printf("Scelta: ");
             scanf("%d", &choose);
        
             switch(choose){
    
                  case 1: 
                      //inserisco una nuova riga sul file FILE_INPUT
                      addNumbers();
                      break;
                  case 2:
    		  //scrivo il risultato in FILE_OUTPUT
                      scriviRis();
                      break;
                  default:
                      printf("Bye!\n");
                      
             }
             
             //Svuoto il buffer dello standard input
             fflush(stdin);
             
             puts("-------");
             
        }
        
        return(0);
    }
    
    void addNumbers(void){ 
    
        // Puntatori ai file
        FILE *in; 
        
        // Numero da inserire
        float num;
    
        // Apro il file FILE_INPUT in lettura e associo il suo indirizzo a un puntatore
        if(!(in = fopen(FILE_INPUT, "a"))){ 
                
            printf("Impossibile aprire il file di input.");
            exit(-1);
            
        } else {
               
             printf("Scrivi il numero da inserire sul file: ");
             scanf("%f", &num);
            
             //Scrivo il numero inserito dall'utente
             fprintf(in, "%.2f\n", num);
             
             //chiudo il canale ai file
             fclose(in); 
        
             puts("Scrittura del numero su file eseguita correttamente");
    
        }
        
    }
    
    void scriviRis(void){ 
    
        //Puntatori ai file
        FILE *in, *out; 
        
        //array che contiene i caratteri estratti
        char line[MAX]; 
        float value = 0, sum = 0; 
        int nrLines = 0; 
    
        //Apro il file FILE_INPUT in lettura e associo il suo indirizzo a un puntatore
        if(!(in = fopen(FILE_INPUT, "r"))){ 
                
            printf("Impossibile aprire il file di input.");
            exit(-1);
            
        } else {
            
            //Apro il file FILE_OUTPUT in scrittura dalla coda. Se non esiste lo crea.
            if(!(out = fopen(FILE_OUTPUT, "a"))){ 
                     
                printf("Impossibile aprire il file di output."); 
                exit(-1);
                
            } else {
                   
                //scorre il file fino alla fine
                while(!(feof(in))){ 
                                    
                     //prelevo una linea di massimo MAX caratteri dall'input
                    fgets(line, MAX, in);  
                    //estraggo il valore reale contenuto nella linea 
                    value = atof(line);
                    //faccio la somma dei valori che di volta in volta estraggo
                    sum += value;  
                    //incremento il numero di linee presenti nel file
                    nrLines++;  
                    
                } 
                
                //Decremento di uno il numero delle righe. Infatti l'ultima riga viene letta anche se vuota
                nrLines--;
                sum -= value;
                
                //Scrivo su file FILE_OUTPUT
                fprintf(out, "Il file di origine contiene al momento %d numeri aventi somma %.2f\n", nrLines, sum); 
    
                //chiudo il canale ai file
                fclose(in); 
                fclose(out);
        
                puts("Scrittura su file eseguita correttamente");
            }
        }
        
    }

  6. #6

    Re: problema ricomplicato, risolto, ma non in maniera ottimale

    Originariamente inviato da fabbio86
    Ciao!

    Ho provato a modificare il programma facendo in modo che possa acquisire anche numeri dall'utente. Questi vengono memorizzati nel file ingresso.txt e suddivisi da un return ("\n"). Il problema ora è che feof() legge una volta di troppo i valori (perchè scandaglia anche la nuova riga vuota), segnala una riga in più di quella che dovrebbe esserci e, stranamente, somma due volte l'ultimo valore (mi sfugge il perchè). Ho ovviato a questo inconveniente facendo:
    ...
    Una soluzione potrebbe essere quella di eliminare la riga
    vuota che crei quando inserisci i dati modificando la
    funzione addNumbers() così:

    codice:
    void addNumbers(void)
    { 
    	// Puntatori ai file
    	FILE *in; 
    	// Numero da inserire
    	float num;
    	// Questa varibile booleana di tipo statica è un flag 
    	static bool first=true;
    	// Apro il file FILE_INPUT in lettura e associo il suo indirizzo a un puntatore
    	if( ( in = fopen(FILE_INPUT, "a") ) <= 0 )
    	{ 
    		printf("Impossibile aprire il file di input.");
    		exit(-1);
    	} 
    	else 
    	{
    		printf("Scrivi il numero da inserire sul file: ");
    		scanf("%f", &num);
    		
    		// Scrivo il carattere invio solo per gli iserimenti successivi al primo
    		if( ! first ) fprintf(in, "\n");
    		// Scrivo il numero inserito dall'utente
    		fprintf(in, "%.2f", num);
    		// Chiudo il canale ai file
    		fclose(in); 
    		
    		puts("Scrittura del numero su file eseguita correttamente");
    	}
    	first = false;
    }
    La seconda possibilità (quella che preferisco )
    segue il procedimento opposto, e cioè ignora, in fase di
    lettura del file "ingresso.txt", le righe che
    non contengono valori numerici validi :
    codice:
    #include <stdio.h>
    #include <stddef.h>
    #include <stdlib.h>
    
    #define MAX 20
    #define FILE_INPUT "ingresso.txt"
    #define FILE_OUTPUT "uscita.txt"
    
    int main()
    {
    	// Variabili
    	int choose = 0;
    	// Prototipi
    	void scriviRis(void);
    	void addNumbers(void);
    	void deleteNumbers(void);
    	
    	while(choose < 3)
    	{
    		puts("Che cosa si desidera fare?");
    		puts("1) Inserire numeri sul file");
    		puts("2) Scrivere la somma dei numeri sul file");
    		puts("Premere un qualunque altro tasto per uscire dal programma");
    		puts("-------");
    		printf("Scelta: ");
    		scanf("%d", &choose);
    		
    		switch(choose)
    		{
    			case 1: 
    				// Inserisco una nuova riga sul file FILE_INPUT
    				addNumbers();
    				break;
    			case 2:
    				// Scrivo il risultato in FILE_OUTPUT
    				scriviRis();
    				break;
    			default:
    				printf("Bye!\n");
    		}
    		// Svuoto il buffer dello standard input
    		fflush(stdin);
    		puts("-------");
    	}
    	return(0);
    }
    
    void addNumbers(void)
    { 
    	// Puntatori ai file
    	FILE *in; 
    	// Numero da inserire
    	float num;
    	// Apro il file FILE_INPUT in lettura e associo il suo indirizzo a un puntatore
    	if( ( in = fopen(FILE_INPUT, "a") ) <= 0 )
    	{ 
    		printf("Impossibile aprire il file di input.");
    		exit(-1);
    	} 
    	else 
    	{
    		printf("Scrivi il numero da inserire sul file: ");
    		scanf("%f", &num);
    		
    		// Scrivo il numero inserito dall'utente
    		fprintf(in, "%.2f\n", num);
    		// Chiudo il canale ai file
    		fclose(in); 
    		
    		puts("Scrittura del numero su file eseguita correttamente");
    	}
    }
    
    void scriviRis(void)
    { 
    	// Puntatori ai file
    	FILE *in, *out; 
    	// Array che contiene i caratteri estratti
    	char line[MAX]; 
    	float value = 0, sum = 0; 
    	int nrLines = 0; 
    	char *valoreValido;
    	// Apro il file FILE_INPUT in lettura e associo il suo indirizzo a un puntatore
    	if( ( in = fopen(FILE_INPUT, "r") ) <=0 )
    	{ 
    		printf("Impossibile aprire il file di input.");
    		exit(-1);
    	}
    	else 
    	{
    		// Apro il file FILE_OUTPUT in scrittura dalla coda. Se non esiste lo crea.
    		if( ( out = fopen(FILE_OUTPUT, "a") ) <= 0 )
    		{ 
    		    printf("Impossibile aprire il file di output."); 
    		    exit(-1);
    		} 
    		else 
    		{
    			// Scorre il file fino alla fine
    			while( ! feof(in)  )
    			{ 
    				// Prelevo una linea di massimo MAX caratteri dall'input
    				valoreValido = fgets(line, MAX, in);  
    				
    				// Estraggo il valore reale contenuto nella linea
    				// Se la stringa non è vuota
    				// Ed è una costante numerica valida
    				if( valoreValido != NULL && ( value = atof(line) ) != 0 )
    				{
    					printf("%s", line);
    					// Faccio la somma dei valori che di volta in volta estraggo
    					sum += value;  
    					// Incremento il numero di linee presenti nel file
    					nrLines++;  
    				}
    			} 
    			// Decremento di uno il numero delle righe. Infatti l'ultima riga viene letta anche se vuota
    			// nrLines--; // Non è più necessario il decremento :-)
    			sum -= value;
    			
    			// Scrivo su file FILE_OUTPUT
    			fprintf(out, "Il file di origine contiene al momento %d numeri aventi somma %.2f\n", nrLines, sum); 
    			
    			// Chiudo il canale ai file
    			fclose(in); 
    			fclose(out);
    			puts("Scrittura su file eseguita correttamente");
    		}
    	}
    }
    Puoi provare 'sporcando' il file 'ingresso.txt' con righe
    vuote e caratteri non numerici.
    Ora la funzione conta e somma solo le righe valide.
    Ho eliminato anche alcuni 'warning' che dava il
    compilatore in fase di controllo delle fopen().
    01010011 01100001 01101101 01110101 01100101 01101100 01100101 01011111 00110111 00110000
    All errors are undocumented features waiting to be discovered.

  7. #7

    Re: Re: problema ricomplicato, risolto, ma non in maniera ottimale

    Originariamente inviato da Samuele_70
    codice:
    ...
    			// Decremento di uno il numero delle righe. Infatti l'ultima riga viene letta anche se vuota
    			// nrLines--; // Non è più necessario il decremento :-)
    			// sum -= value; // Anche questa sottrazione non è più necessaria
    			
    ...
    Mi correggo
    Anche la sottrazione "sum -= value;" va eliminata ovviamente
    01010011 01100001 01101101 01110101 01100101 01101100 01100101 01011111 00110111 00110000
    All errors are undocumented features waiting to be discovered.

  8. #8

    Mitici!

    Grazie dell'aiuto!

    Ora è davvero tutto chiaro!

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.