Fscanf

Forum dedicato alla programmazione.

Moderatore: Staff

Regole del forum
1) Citare in modo preciso il linguaggio di programmazione usato.
2) Se possibile portare un esempio del risultato atteso.
3) Leggere attentamente le risposte ricevute.
4) Scrivere i messaggi con il colore di default, evitare altri colori.
5) Scrivere in Italiano o in Inglese, se possibile grammaticalmente corretto, evitate stili di scrittura poco chiari, quindi nessuna abbreviazione tipo telegramma o scrittura stile SMS o CHAT.
6) Appena registrati è consigliato presentarsi nel forum dedicato.

La non osservanza delle regole porta a provvedimenti di vari tipo da parte dello staff, in particolare la non osservanza della regola 5 porta alla cancellazione del post e alla segnalazione dell'utente. In caso di recidività l'utente rischia il ban temporaneo.
Rispondi
afterjames
Linux 0.x
Linux 0.x
Messaggi: 64
Iscritto il: lun 14 gen 2008, 14:14

Fscanf

Messaggio da afterjames »

Salve a tutti.Mi sono imbattuto in una cosa molto strana.Non capisco perchè se faccio:

Codice: Seleziona tutto

...
fscanf(fptr,"%d",&num_stud);
printf("%d\n",num_stud);
fscanf(fptr,"%s",car); 
va tutto bene, num_stud contiene il valore giusto.Se provo invece a fare

Codice: Seleziona tutto

...
fscanf(fptr,"%d",&num_stud);
fscanf(fptr,"%s",car); 
printf("%d\n",num_stud);
num_stud contiene zero!Ma non la tocco!Non riesco a capire il perchè.

Avatar utente
Blizzard
Master
Master
Messaggi: 1509
Iscritto il: mar 2 gen 2007, 22:53
Nome Cognome: Giovanni Santostefano
Slackware: 12.2
Kernel: 2.6.27.7-smp
Desktop: Fluxbox
Contatta:

Re: Fscanf

Messaggio da Blizzard »

bella strana come cosa...
non potresti postare un po più di codice per aiutare a capire meglio il flusso di programma?
qui ci sono in gioco puntatori.... potrebbe anche essere che l'errore è sperduto da qualche altra parte :p

Avatar utente
FireEater
Linux 3.x
Linux 3.x
Messaggi: 508
Iscritto il: sab 5 feb 2005, 0:00
Nome Cognome: Giuseppe M.
Slackware: Current
Kernel: 2.6.32.7-smp
Desktop: kde 4.3.4
Località: Cagliari <---> Torino

Re: Fscanf

Messaggio da FireEater »

Si, posta più codice, visto così sembra impossibile che possa succedere quello che dici.

posta anche il contenuto del file che stai leggendo.

Avatar utente
absinthe
Iper Master
Iper Master
Messaggi: 2354
Iscritto il: dom 15 mag 2005, 0:00
Nome Cognome: Matteo Nunziati
Slackware: 12.1 - defunct
Kernel: 2.6.32-5-amd64
Desktop: gnome
Distribuzione: debian squeeze
Località: Prato
Contatta:

Re: Fscanf

Messaggio da absinthe »

ti sei scordato molto probabilmente di passare l'indirizzo della variabile car:
se car è di tipo char tu usi
fscanf(fptr,"%s",car);
ma devi usare
fscanf(fptr,"%s",&car);
se car è un array può darsi che non sia di dimensione giusta...: quando allochi l'altra variabile? subito dopo car o subito prima? ti sei ricordato che un array di caratteri deve avere n+1 elementi dove n è la lunghezza della stringa e il +1 serve per lo zero terminale?

imho,
M

Avatar utente
robbybby
Linux 4.x
Linux 4.x
Messaggi: 1223
Iscritto il: sab 16 dic 2006, 10:48
Slackware: 13.1 / 64 bit
Kernel: 3.3.x
Desktop: KDE 4.4.5
Località: Fra Trantor e Terminus

Re: Fscanf

Messaggio da robbybby »

Piccola correzione: se car e' di tipo char devi fare:
fscanf(fptr,"%c",&car);

birg81
Linux 3.x
Linux 3.x
Messaggi: 760
Iscritto il: lun 16 gen 2006, 10:57
Nome Cognome: Biagio
Slackware: 12.2
Kernel: 3.4.7
Desktop: LxDE
Distribuzione: ArchLinux
Località: Castellammare di Stabia (NA)
Contatta:

Re: Fscanf

Messaggio da birg81 »

la sparo li come una stronzata, perché forse &num_stud contiene un indirizzo e non un valore e ka conseguenza ad un'errata sintassi e' che punti al nulla / void / 0 a causa del casting?!

putroppo non mastico programmazzione di c/c++ dall'esame di programmazione 2 e sono passati diversi anni

afterjames
Linux 0.x
Linux 0.x
Messaggi: 64
Iscritto il: lun 14 gen 2008, 14:14

Re: Fscanf

Messaggio da afterjames »

Cerco di chiarire.Car è un array, sintatticamente è giusto:

Codice: Seleziona tutto

fptr=fopen(filename,"r");
int num_stud;
char car[9];
while(!feof(fptr)){
fscanf(fptr,"%d",&num_stud);
fscanf(fptr,"%s",car);
}
Il file studenti.txt contiene informazioni così strutturate:
139 (13/03), 200 (29/06)
Quindi leggo prima il numero, eppoi metto il resto in una stringa di dimensione +1 per contenere il terminatore.La lettura successiva di car, perchè dovrebbe danneggiare la precedente?Il file pointer non viene incrementato da una fscanf?Ovviamente il problema è risolvibile, ma non capisco questo comportamento.

Avatar utente
boh
Linux 4.x
Linux 4.x
Messaggi: 1027
Iscritto il: ven 16 set 2005, 0:00
Slackware: 14.2 (x64)
Kernel: 4.4.111
Desktop: KDE 4.14.32
Località: Milano
Contatta:

Re: Fscanf

Messaggio da boh »

Per quanto ne so la feof per stabilire se ha trovato la fine del file deve basarsi sull'ultima fscanf, quindi il tuo codice è errato nella gestione del ciclo while.

Codice: Seleziona tutto

fptr=fopen(filename,"r");
int num_stud;
char car[9];
fscanf(fptr,"%d",&num_stud);
fscanf(fptr,"%s",car);
while(!feof(fptr)){
//...Quello che devi fare...
fscanf(fptr,"%d",&num_stud);
fscanf(fptr,"%s",car);
}
Questa è la gestione corretta.
Inoltre consiglierei un controllo all'apertura del file per verificare che l'fopen non restituisca NULL.

Quindi:

Codice: Seleziona tutto

if(fptr=fopen(filename,"r")) {
int num_stud;
char car[9];
fscanf(fptr,"%d",&num_stud);
fscanf(fptr,"%s",car);
while(!feof(fptr)){
//...Quello che devi fare...
fscanf(fptr,"%d",&num_stud);
fscanf(fptr,"%s",car);
}
}
else
printf("Problemi con il file sorgente");
Ora al di là del controllo verifica se l'errore poteva essere dato dall'errato ciclo while, anche se mi sembra strano.
"Be yourself. Everyone else is already taken." ~ Oscar Wilde

Avatar utente
FireEater
Linux 3.x
Linux 3.x
Messaggi: 508
Iscritto il: sab 5 feb 2005, 0:00
Nome Cognome: Giuseppe M.
Slackware: Current
Kernel: 2.6.32.7-smp
Desktop: kde 4.3.4
Località: Cagliari <---> Torino

Re: Fscanf

Messaggio da FireEater »

afterjames ha scritto:Cerco di chiarire.Car è un array, sintatticamente è giusto:

Codice: Seleziona tutto

fptr=fopen(filename,"r");
int num_stud;
char car[9];
while(!feof(fptr)){
fscanf(fptr,"%d",&num_stud);
fscanf(fptr,"%s",car);
}
Il file studenti.txt contiene informazioni così strutturate:
139 (13/03), 200 (29/06)
Quindi leggo prima il numero, eppoi metto il resto in una stringa di dimensione +1 per contenere il terminatore.La lettura successiva di car, perchè dovrebbe danneggiare la precedente?Il file pointer non viene incrementato da una fscanf?Ovviamente il problema è risolvibile, ma non capisco questo comportamento.
Non uso c da un po' ma se non sbaglio il tuo errore sta nel fatto che la fscanf acquisice tutta la figa in colpo solo, mentre tu cerchi di leggere 1 riga con 2 fscanf separate.

Dovresti utilizzare un unica istruzione:

Codice: Seleziona tutto

fscanf(fptr,"%d %s",&num_stud,car);
Quello che succede con il tuo codice è che(supponendo il file non vuoto):
Al primo ciclo leggi il numero, lo metti in "num_stud" e perdi il resto della stringa, la seconda fscanf invece legge tutta la seconda riga del file "fottendoti" anche il numero e lasciandoti "num_stud" con lo zero di fine riga.

Ciao
FE

Mario Vanoni
Iper Master
Iper Master
Messaggi: 3174
Iscritto il: lun 3 set 2007, 21:20
Nome Cognome: Mario Vanoni
Slackware: 12.2
Kernel: 3.0.4 statico
Desktop: fluxbox/seamonkey
Località: Cuasso al Monte (VA)

Re: Fscanf

Messaggio da Mario Vanoni »

Fire_eater ha scritto:
afterjames ha scritto:Cerco di chiarire.Car è un array, sintatticamente è giusto:

Codice: Seleziona tutto

fptr=fopen(filename,"r");
int num_stud;
char car[9];
while(!feof(fptr)){
fscanf(fptr,"%d",&num_stud);
fscanf(fptr,"%s",car);
}
Il file studenti.txt contiene informazioni così strutturate:
139 (13/03), 200 (29/06)
Quindi leggo prima il numero, eppoi metto il resto in una stringa di dimensione +1 per contenere il terminatore.La lettura successiva di car, perchè dovrebbe danneggiare la precedente?Il file pointer non viene incrementato da una fscanf?Ovviamente il problema è risolvibile, ma non capisco questo comportamento.
Non uso c da un po' ma se non sbaglio il tuo errore sta nel fatto che la fscanf acquisice tutta la figa in colpo solo, mentre tu cerchi di leggere 1 riga con 2 fscanf separate.

Dovresti utilizzare un unica istruzione:

Codice: Seleziona tutto

fscanf(fptr,"%d %s",&num_stud,car);
Quello che succede con il tuo codice è che(supponendo il file non vuoto):
Al primo ciclo leggi il numero, lo metti in "num_stud" e perdi il resto della stringa, la seconda fscanf invece legge tutta la seconda riga del file "fottendoti" anche il numero e lasciandoti "num_stud" con lo zero di fine riga.

Ciao
FE
Concordo al 100%, se vuoi leggere in due passi, devi usare rewind(3) e co.

afterjames
Linux 0.x
Linux 0.x
Messaggi: 64
Iscritto il: lun 14 gen 2008, 14:14

Re: Fscanf

Messaggio da afterjames »

Quello che succede con il tuo codice è che(supponendo il file non vuoto):
Al primo ciclo leggi il numero, lo metti in "num_stud" e perdi il resto della stringa, la seconda fscanf invece legge tutta la seconda riga del file "fottendoti" anche il numero e lasciandoti "num_stud" con lo zero di fine riga.
Scusa ma come fa a "fottermi" il numero???é in una variabile ormai!Perchè dovrebbe sovrascriverlo?Eppoi la fscanf è come la scanf, solo che lo stream di input è un file e non stdin..Quindi quando trova uno spazio o \n si ferma..

Avatar utente
FireEater
Linux 3.x
Linux 3.x
Messaggi: 508
Iscritto il: sab 5 feb 2005, 0:00
Nome Cognome: Giuseppe M.
Slackware: Current
Kernel: 2.6.32.7-smp
Desktop: kde 4.3.4
Località: Cagliari <---> Torino

Re: Fscanf

Messaggio da FireEater »

afterjames ha scritto: Scusa ma come fa a "fottermi" il numero???é in una variabile ormai!Perchè dovrebbe sovrascriverlo?Eppoi la fscanf è come la scanf, solo che lo stream di input è un file e non stdin..Quindi quando trova uno spazio o \n si ferma..
Ok. Fortuna che ho detto che non ricordavo. :) Hai ragione, la scanf si ferma al primo spazio che incontra. Il discorso di fotterti il num era riferito al ciclo(ma è un altro discorso dato che la fscanf non legge tutta la riga).

Non so che dirti, ho provato il tuo codice, sul mio pc funziona bene. In num_stud ci va zero solo se faccio la stringa di 8. Con 9 va benissimo.

Ciao

Mario Vanoni
Iper Master
Iper Master
Messaggi: 3174
Iscritto il: lun 3 set 2007, 21:20
Nome Cognome: Mario Vanoni
Slackware: 12.2
Kernel: 3.0.4 statico
Desktop: fluxbox/seamonkey
Località: Cuasso al Monte (VA)

Re: Fscanf

Messaggio da Mario Vanoni »

afterjames ha scritto:
Quello che succede con il tuo codice è che(supponendo il file non vuoto):
Al primo ciclo leggi il numero, lo metti in "num_stud" e perdi il resto della stringa, la seconda fscanf invece legge tutta la seconda riga del file "fottendoti" anche il numero e lasciandoti "num_stud" con lo zero di fine riga.
Scusa ma come fa a "fottermi" il numero???é in una variabile ormai!Perchè dovrebbe sovrascriverlo?Eppoi la fscanf è come la scanf, solo che lo stream di input è un file e non stdin..Quindi quando trova uno spazio o \n si ferma..
Il secondo fscanf usa car, definito car[9], 8 caratteri + \0
studenti.txt contiene 24 chars + \n
ai tempi passati dava un "core dumped"

Avatar utente
robbybby
Linux 4.x
Linux 4.x
Messaggi: 1223
Iscritto il: sab 16 dic 2006, 10:48
Slackware: 13.1 / 64 bit
Kernel: 3.3.x
Desktop: KDE 4.4.5
Località: Fra Trantor e Terminus

Re: Fscanf

Messaggio da robbybby »

Non mi e' mai piaciuta, la fscanf().
Io uso fgets(), oppure fread() se ho un file binario, e poi mi faccio il parsing della riga letta. Se trova qualcosa di inaspettato (e nel mondo reale succede piu' spesso di quanto pensi :( ) non pianto niente.

Avatar utente
FireEater
Linux 3.x
Linux 3.x
Messaggi: 508
Iscritto il: sab 5 feb 2005, 0:00
Nome Cognome: Giuseppe M.
Slackware: Current
Kernel: 2.6.32.7-smp
Desktop: kde 4.3.4
Località: Cagliari <---> Torino

Re: Fscanf

Messaggio da FireEater »

robbybby ha scritto:Non mi e' mai piaciuta, la fscanf().
Io uso fgets(), oppure fread() se ho un file binario, e poi mi faccio il parsing della riga letta. Se trova qualcosa di inaspettato (e nel mondo reale succede piu' spesso di quanto pensi :( ) non pianto niente.
quoto

Rispondi