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().