PDA

View Full Version : [C] Lettura da file e stampa a video


Xfree
06-07-2007, 20:37
Ciao a tutti.
Ho un problema con una parte di esercizio e se non lo risolvo non posso andare avanti. :D
Questo il testo della parte al momento interessata:

Una biblioteca ha immagazzinato in un file di testo i dati relativi ai libri posseduti.
Nel file di testo sono memorizzate, utilizzando tre righe del file per ogni libro, le seguenti informazioni

elenco degli autori
titolo del libro
tipologia(giallo,azione,ecc...)


Questo il codice

#include<stdio.h>
#include<string.h>

#define MAX 50

struct tlibro{
char autori[MAX];
char titolo[MAX];
char tipologia[MAX];
};

struct tlibro libro;

main()
{
int n;
FILE *fp;
fp=fopen("libri.txt","r");
if(fp==NULL)
printf("Si e' verificato un'errore nell'apertura del file\n");
else{
int c;
while(!feof(fp)){
n=fread(&libro,sizeof(struct tlibro),1,fp);
printf("%s\n",libro.autori);
printf("%s\n",libro.titolo);
printf("%s\n",libro.tipologia);
}
fclose(fp);
}
system("pause");
}


Questo il file di testo che ho creato per prova

DANTE
LA DIVINA COMMEDIA
COMMEDIA
DESCARTES
DISCORSO SUL METODO
SAGGISTICA
UMBERTO ECO
IL NOME DELLA ROSA
LETTERATURA


E questo è invece è l'output che ottengo a video
http://img456.imageshack.us/img456/4426/outputym8.png

Il problema, secondo me, è che leggendo MAX caratteri dalla stringa si va a prendere anche quelle successive,ho provato anche con fgets() ed fscanf() ma senza risultato.
Mi sapreste aiutare? :stordita:

cionci
07-07-2007, 10:11
Strano, fgets dovrebbe risolvere: http://www.cplusplus.com/reference/clibrary/cstdio/fgets.html
Infatti legge fino al primo newline che incontra...

Sicuramente fread e fscanf non sono adatte, fread legge una numero di byte preimpostato, mentre fscanf si ferma al primo carattere di spazio, tab o newline...

Xfree
07-07-2007, 10:30
Perfetto, con fgets() ho risolto, ieri l'avevo usata in modo improprio.
Ora mi sto scervellando su come mettere ciò che leggo nella struct :mc:

cionci
07-07-2007, 10:40
Ora mi sto scervellando su come mettere ciò che leggo nella struct :mc:
Basta passare alla fgets la stringa relativa all'elemento che vuoi leggere.
Fai tre fgets ed ad ognuna passi un elemento della struttura diverso ;)

Xfree
07-07-2007, 10:53
Mitico sta funzionando :D

#include<stdio.h>
#include<string.h>

#define MAX 50

struct tlibro{
char autori[MAX];
char titolo[MAX];
char tipologia[MAX];
};

struct tlibro libro;


main()
{
int n;
char aux[MAX];
FILE *fp;
fp=fopen("libri.txt","r");
if(fp==NULL)
printf("Si e' verificato un'errore nell'apertura del file\n");
else{
int c;
while(!feof(fp)){
fgets(libro.autori,MAX,fp);
fgets(libro.titolo,MAX,fp);
fgets(libro.tipologia,MAX,fp);
printf("%s",libro.autori);
printf("%s",libro.titolo);
printf("%s",libro.tipologia);
}
fclose(fp);
}
system("pause");
}



http://img412.imageshack.us/img412/7018/outputbg8.th.png (http://img412.imageshack.us/my.php?image=outputbg8.png)

Ma sta funzionando perché ogni fgets() legge fino a fine stringa ed essendocene tre di fgets() leggo tre stringhe alla volta, che poi vanno nella struct...ho capito giusto? :stordita:

andbin
07-07-2007, 10:58
Ma sta funzionando perché ogni fgets() legge fino a fine stringa ed essendocene tre di fgets() leggo tre stringhe alla volta, che poi vanno nella struct...ho capito giusto? :stordita:Sì. Comunque sarebbe più valido e logico che i dati del singolo "record" siano su una unica riga, separati da un delimitatore.

cionci
07-07-2007, 11:03
Sì, ma al posto di sizeof(aux) devi mettere MAX...
Infatti la fgets se trovasse una stringa molto lunga si fermerebbe prima della fine della riga e visto che la stringa della struttura è lunga MAX devi specificare quello nel campo...

Edit: ignora quello che avevo scritto...fgets legge da sola un massimo di MAX-1 caratteri...

Xfree
07-07-2007, 11:09
Sì. Comunque sarebbe più valido e logico che i dati del singolo "record" siano su una unica riga, separati da un delimitatore.

Si lo so, ma questo esercizio è formulato in questa maniera; ed è per questo all'inizio mi è sembrato strano, poi io non è che abbia tutta questa esperienza. :D
Ma ora mi hai fatto venire la curiosità, come si farebbe a leggere i dati separati da delimitatore?

cionci
07-07-2007, 11:16
O fai una tua funzioncina ad hoc che scorre la stringa e la scompone...o usi strtok...
http://www.cplusplus.com/reference/clibrary/cstring/strtok.html
Anche se sinceramente strtok non mi è mai stata molto simpatica...
In teoria ci sarebbe anche la possibilità di usare sscanf indicando nello specificatore di tipo il carattere a cui deve arrestare la lettura della stringa...

Xfree
07-07-2007, 11:18
Sì, ma al posto di sizeof(aux) devi mettere MAX...
Infatti la fgets se trovasse una stringa molto lunga si fermerebbe prima della fine della riga e visto che la stringa della struttura è lunga MAX devi specificare quello nel campo...

Edit: ignora quello che avevo scritto...fgets legge da sola un massimo di MAX-1 caratteri...

Si comunque hai ragione, perché è il numero di caratteri da leggere e non la dimensione.

Xfree
07-07-2007, 11:22
O fai una tua funzioncina ad hoc che scorre la stringa e la scompone...o usi strtok...
http://www.cplusplus.com/reference/clibrary/cstring/strtok.html
Anche se sinceramente strtok non mi è mai stata molto simpatica...
In teoria ci sarebbe anche la possibilità di usare sscanf indicando nello specificatore di tipo il carattere a cui deve arrestare la lettura della stringa...

Queste due funzioni in effetti non le abbiamo mai affrontate a lezione.
Grazie per l'aiuto! ;)

cionci
07-07-2007, 11:33
sscanf è uguale alla scanf, solo che effettua la lettura da una stringa invece che dallo standard input...