View Full Version : [C] Lettura e scrittura di File Testo
Salve ragazzi.
Sto scrivendo un semplice algoritmo ed in esso devo leggere delle stringhe da tastiera, memorizzarle in un file testo e poi ristamparle a video.
Per memorizzare le stringhe ho usato il codice seguente:
-----------------------------------------------------------------------
for(i=0;i<n;i++)
{
printf("Inserisci la stringa numero %d:\n", i+1);
while((ch=getchar()) != EOF)
fprintf(fp,"%c", ch);
}
----------------------------------------------------------------------
Però non riesco a trovare il modo di leggere da questo file. Ho provato in molti modi ma ottengo solo una à. Il file l'ho aperto con il comando a+ in modo da poterci appendere e leggere.
Aspetto vostre illuminazioni...
Fammi capire...ma il file se lo apri con notepad come lo vedi ?
Fenomeno85
06-09-2004, 17:39
aspè che ci provo anchio dato che devo imparare a leggere i file di testo :D
~§~ Sempre E Solo Lei ~§~
Ziosilvio
06-09-2004, 18:12
Originariamente inviato da fant3
Per memorizzare le stringhe ho usato il codice seguente:
-----------------------------------------------------------------------
for(i=0;i<n;i++)
{
printf("Inserisci la stringa numero %d:\n", i+1);
while((ch=getchar()) != EOF)
fprintf(fp,"%c", ch);
}
----------------------------------------------------------------------
:nonsifa: :nonsifa: :nonsifa: usare una *printf per scrivere un singolo carattere...
fputc(ch,fp);
Ah: la fine della riga e' proprio un EOF (Ctrl+D sotto Linux)? Tieni conto che, comunque, quando premi Invio viene inserito un newline, quindi anche questo dovrebbe funzionare:
printf("Inserisci la stringa numero %d:\n", i+1);
while (1) {
fputc(fp,(ch=getchar()));
if (ch=='\n') break;
}
A proposito: ch e' un char o un int?
Se vuoi potergli assegnare il valore EOF, deve essere int.
Però non riesco a trovare il modo di leggere da questo file. Ho provato in molti modi ma ottengo solo una à. Il file l'ho aperto con il comando a+ in modo da poterci appendere e leggere.
Se provi a leggere dal file dopo aver finito di scriverci su, leggi la sua fine.
Esegui una rewind(fp) tra il momento in cui scrivi l'ultimo carattere e quello in cui provi a leggere il file.
Per leggere... beh, guarda che leggere righe di testo di lunghezza arbitraria non e' facile come sembra... puoi stampare tutto il file semplicemente leggendolo un carattere alla volta, e stampando il carattere appena letto.
Io eviterei l'uso di EOF...ma userei feof...
Fenomeno85
06-09-2004, 19:09
orca sbaglio qualcosa :wtf: nella letterura
while (!feof(fp)){
fgets (&x, 1, fp);
printf ("%c", x);
}
~§~ Sempre E Solo Lei ~§~
Originariamente inviato da Ziosilvio
printf("Inserisci la stringa numero %d:\n", i+1);
while (1) {
fputc(fp,(ch=getchar()));
if (ch=='\n') break;
}
Allora rispondo con ordine:
>Cionci:
-Se apro il file testo creato ci sono i caratteri che immetto quindi li scrive bene.
-Scusa l'ignoranza ma cosa cambia fra eof e feof?
>ZioSilvio:
-Perchè non usare la fprintf? Che problemi porterebbe?
-ch l'ho dichiarato come intero.
-Nel tuo codice sopra riportato la fputc mi sembra che abbia i parametri al contrario.
Comunque l'esercizio mi chiede di usare le funzioni fscanf, fprintf, getc e putc.
Lo standard prevede di usare feof...e questo vuol dire che il metodo con EOF possa non funzionare con tutti is sitemi operativi...
feof è una funzione... che prende come parametro un FILE * e ritorna un numero diverso da 0 se è stata raggiunta la fine del file...
Ziosilvio
06-09-2004, 20:56
Originariamente inviato da fant3
-Perchè non usare la fprintf? Che problemi porterebbe?
fprintf è una funzione di uso generale, con un codice complesso; fputc è una funzione di uso specifico, con un codice semplice.
Se fai molte chiamate, usare fputc anziché fprintf velocizza il programma.
-ch l'ho dichiarato come intero.
Benissimo; vuol dire che hai capito come si usa EOF.
-Nel tuo codice sopra riportato la fputc mi sembra che abbia i parametri al contrario.
Vero! Dovrebbe essere:
fputc((ch=getchar()),fp);
L'avevo pure ricontrollata due volte nella man page... :cry:
Mi sa che sto diventando :old: e :tapiro:
Chiedo scusa.
Comunque l'esercizio mi chiede di usare le funzioni fscanf, fprintf, getc e putc.
Ah, allora la tua chiamata a fprintf va bene.
Hai più provato a mettere rewind prima delle fscanf? Dà ancora quell'output strano?
Giusto se apri con a+t: fseek(f, 0, SEEK_SET);
Ziosilvio
06-09-2004, 21:00
Originariamente inviato da cionci
Lo standard prevede di usare feof...e questo vuol dire che il metodo con EOF possa non funzionare con tutti is sitemi operativi...
OK, ma il K&R dice che fgetc (quindi anche le sue varianti getc e getchar), se incontra la fine del file, restituisce EOF.
Ziosilvio
06-09-2004, 21:03
Originariamente inviato da cionci
Giusto se apri con a+t: fseek(f, 0, SEEK_SET);
Peraltro, sempre il K&R dice che:
rewind(fp);
equivale esattamente a:
fseek(fp,0L,SEEK_SET);
clearerr(fp);
>Cionci:
L'apertura file a+t cosa produce?
Io ho usato la a+.
Per quanto riguarda le scrittura delle stringhe su file va bene poichè il file testo generato riporta quello che digito.
Ora non mi è molto chiaro il funzionamento della fscanf.
Ho provato il seguente codice ma di sicuro c'è qualcosa di sbagliato perchè mi restituisce "!!".
Ah ho inserito rewind fp fra le operazioni di lettura e scrittura ma non è quello il problema...o almeno non solo quello :)
-------------------------------------------------------------------
for(j=0;j<len;j++)
{
fscanf(fp, "&d", &s);
putchar(s);
}
-------------------------------------------------------------------
s è un intero
con len indico la lunghezza del file, ma ho un dubbio. E' corretto calcolare len in questo modo?
-------------------------------------------------------------------
len=0;
while((ch=getchar()) != EOF)
fprintf(fp,"%c", ch);
len++;
------------------------------------------------------------------
Qualcuno sa dove posso trovare qualche spiegazione sulla scanf perchè ho trovato poco sinora.
Ziosilvio
06-09-2004, 23:07
Originariamente inviato da fant3
Ora non mi è molto chiaro il funzionamento della fscanf.
fscanf, il cui prototipo è:
int fscanf(FILE *stream, const char *fmt, ...);
prende come argomento un puntatore a file, una stringa di formato, e una sequenza di puntatori.
fscanf(fp,fmt,arg1[,arg2,...]) legge dal file fp una sequenza di caratteri corrispondente alla stringa di formato fmt.
Ogni volta che in fmt c'è una sequenza del tipo "%t", legge la sequenza successiva come se fosse una rappresentazione di un oggetto di tipo t, e lo scrive nella zona di memoria puntata dall'argN corrispondente.
Per esempio:
fscanf(stdin,"%d",&n);
legge dallo standard input una sequenza di caratteri che rappresenta un intero in notazione decimale, e lo scrive nella zona di memoria il cui indirizzo è quello della variabile n (in breve, nella variabile n): è il modo più immediato per inizializzare una variabile con un valore scelto dall'utente, anche se spesso non il migliore.
Ho provato il seguente codice ma di sicuro c'è qualcosa di sbagliato perchè mi restituisce "!!".
Ah ho inserito rewind fp fra le operazioni di lettura e scrittura ma non è quello il problema...o almeno non solo quello :)
-------------------------------------------------------------------
for(j=0;j<len;j++)
{
fscanf(fp, "&d", &s);
putchar(s);
}
-------------------------------------------------------------------
s è un intero
con len indico la lunghezza del file, ma ho un dubbio. E' corretto calcolare len in questo modo?
-------------------------------------------------------------------
len=0;
while((ch=getchar()) != EOF)
fprintf(fp,"%c", ch);
len++;
------------------------------------------------------------------
Dunque... se ci fai caso, alla fine del ciclo con getchar, len vale sempre 1.
Devi racchiudere la fprintf e il len++ tra parentesi graffe.
In alternativa, puoi usare la forma idiomatica:
for (len=0; (ch=getchar()) != EOF; len++)
fprintf(fp,"%c",ch);
La parte con la fscanf contiene una svista e un errore concettuale.
La svista è che i formattatori iniziano con % e non con &: così è come se tu gli avessi chiesto "leggi da fp un carattere & e un carattere d".
L'errore concettuale è che il formattatore %d significa una stringa che rappresenta un numero intero in notazione decimale, quindi una fscanf(pf,"%d",&s) comincia a leggere da fp un carattere dopo l'altro finché:
- o incontra una lettera, e allora capisce che c'è qualcosa che non va, rimette l'ultimo carattere letto al suo posto nel file, non altera il contenuto di s, e restituisce 0;
- oppure incontra una cifra, nel qual caso continua a leggere finché ci sono cifre, aggiorna il contenuto di s col valore che ha trovato, e restituisce 1.
Se, come ho capito, devi semplicemente stampare il file su schermo, una fscanf come la tua va bene, ma s deve essere di tipo char e il formattatore deve essere %c.
Qualcuno sa dove posso trovare qualche spiegazione sulla scanf perchè ho trovato poco sinora.
Su un qualunque buon manuale di linguaggio C, per esempio il Kernighan&Ritchie, oppure il Deitel&Deitel.
E, naturalmente, nel manuale del compilatore (o nelle man pages di Linux).
Il K&R è un po' vecchio come manuale...
Io sinceramente non mi affiderei molto su EOF...poi fate vobis...
Riguardo al mettere la t dopo il modo di apertura (lo puoi fare per qualsiasi modalità):
t sta per text
b sta per binary
Il default è t, ma in teoria è possibile modificare la modalità di apertura di default...quindi se uno vuole essere sicuro è meglio specificare...
grazie ZioSilvio per i consigli.
Effettivamente ieri avevo confuso i % con & ed avevo mancato le graffe nel ciclo di scrittura....sarà stata l'ora tarda a farmi sbagliare :D
Ora va tutto bene, il file viene scritto e letto correttamente.
Visto che l'esercizio vuole il tutto sotto forma di function di tipo void. Ho provato passando cosi':
text(fp, &len, n)
void text(FILE *fp, int *dim, int n)
ma credo sia sbagliato perchè quando provo ad aprire manualmente il file testo c'è quello che scrivo, ma quando eseguo l'algoritmo non legge nulla. Forse sbaglio nel passaggio del file testo vero?
Ok ragazzi ho risolto.
void text(FILE *fp, int *dim, int n)
text(fp, &len, n)
Prima non funzionava perchè non leggeva la lunghezza del file. Ho messo una variabile locale nella funzione che legge la lunghezza e poi alla fine la memorizza nel puntatore da passare al main.
Grazie a tutti per l'aiuto siete stati gentilisismi.
;)
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.