Repository 32bit  Forum
Repository 64bit  Wiki

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.

Fscanf

Messaggioda afterjames » gio feb 21, 2008 18:56

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è.
afterjames
Linux 1.0
Linux 1.0
 
Messaggi: 64
Iscritto il: lun gen 14, 2008 14:14

Re: Fscanf

Messaggioda Blizzard » gio feb 21, 2008 19:31

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
Blizzard
Master
Master
 
Messaggi: 1509
Iscritto il: mar gen 02, 2007 22:53
Nome Cognome: Giovanni Santostefano
Slackware: 12.2
Kernel: 2.6.27.7-smp
Desktop: Fluxbox

Re: Fscanf

Messaggioda FireEater » gio feb 21, 2008 19:43

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
FireEater
Linux 2.6
Linux 2.6
 
Messaggi: 508
Iscritto il: sab feb 05, 2005 0:00
Località: Cagliari <---> Torino
Nome Cognome: Giuseppe M.
Slackware: Current
Kernel: 2.6.32.7-smp
Desktop: kde 4.3.4

Re: Fscanf

Messaggioda absinthe » gio feb 21, 2008 20:11

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
absinthe
Iper Master
Iper Master
 
Messaggi: 2354
Iscritto il: sab mag 14, 2005 23:00
Località: Prato
Nome Cognome: Matteo Nunziati
Slackware: 12.1 - defunct
Kernel: 2.6.32-5-amd64
Desktop: gnome
Distribuzione: debian squeeze

Re: Fscanf

Messaggioda robbybby » gio feb 21, 2008 20:47

Piccola correzione: se car e' di tipo char devi fare:
fscanf(fptr,"%c",&car);
Avatar utente
robbybby
Linux 3.x
Linux 3.x
 
Messaggi: 1178
Iscritto il: sab dic 16, 2006 10:48
Località: Fra Trantor e Terminus
Slackware: 13.1 / 64 bit
Kernel: 3.3.x
Desktop: KDE 4.4.5

Re: Fscanf

Messaggioda birg81 » gio feb 21, 2008 23:40

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
birg81
Linux 2.6
Linux 2.6
 
Messaggi: 760
Iscritto il: lun gen 16, 2006 10:57
Località: Castellammare di Stabia (NA)
Nome Cognome: Biagio
Slackware: 12.2
Kernel: 3.4.7
Desktop: LxDE
Distribuzione: ArchLinux

Re: Fscanf

Messaggioda afterjames » ven feb 22, 2008 12:14

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.
afterjames
Linux 1.0
Linux 1.0
 
Messaggi: 64
Iscritto il: lun gen 14, 2008 14:14

Re: Fscanf

Messaggioda boh » ven feb 22, 2008 13:24

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
boh
Linux 2.6
Linux 2.6
 
Messaggi: 953
Iscritto il: gio set 15, 2005 23:00
Località: Milano
Slackware: 14.1 (x64)
Kernel: 3.14.1
Desktop: KDE 4.13.3

Re: Fscanf

Messaggioda FireEater » ven feb 22, 2008 17:33

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
Avatar utente
FireEater
Linux 2.6
Linux 2.6
 
Messaggi: 508
Iscritto il: sab feb 05, 2005 0:00
Località: Cagliari <---> Torino
Nome Cognome: Giuseppe M.
Slackware: Current
Kernel: 2.6.32.7-smp
Desktop: kde 4.3.4

Re: Fscanf

Messaggioda Mario Vanoni » ven feb 22, 2008 17:52

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.
Mario Vanoni
Iper Master
Iper Master
 
Messaggi: 3174
Iscritto il: lun set 03, 2007 20:20
Località: Cuasso al Monte (VA)
Nome Cognome: Mario Vanoni
Slackware: 12.2
Kernel: 3.0.4 statico
Desktop: fluxbox/seamonkey

Re: Fscanf

Messaggioda afterjames » ven feb 22, 2008 17:54

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..
afterjames
Linux 1.0
Linux 1.0
 
Messaggi: 64
Iscritto il: lun gen 14, 2008 14:14

Re: Fscanf

Messaggioda FireEater » ven feb 22, 2008 19:07

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
Avatar utente
FireEater
Linux 2.6
Linux 2.6
 
Messaggi: 508
Iscritto il: sab feb 05, 2005 0:00
Località: Cagliari <---> Torino
Nome Cognome: Giuseppe M.
Slackware: Current
Kernel: 2.6.32.7-smp
Desktop: kde 4.3.4

Re: Fscanf

Messaggioda Mario Vanoni » ven feb 22, 2008 19:44

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"
Mario Vanoni
Iper Master
Iper Master
 
Messaggi: 3174
Iscritto il: lun set 03, 2007 20:20
Località: Cuasso al Monte (VA)
Nome Cognome: Mario Vanoni
Slackware: 12.2
Kernel: 3.0.4 statico
Desktop: fluxbox/seamonkey

Re: Fscanf

Messaggioda robbybby » ven feb 22, 2008 20:52

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
robbybby
Linux 3.x
Linux 3.x
 
Messaggi: 1178
Iscritto il: sab dic 16, 2006 10:48
Località: Fra Trantor e Terminus
Slackware: 13.1 / 64 bit
Kernel: 3.3.x
Desktop: KDE 4.4.5

Re: Fscanf

Messaggioda FireEater » ven feb 22, 2008 22:03

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
Avatar utente
FireEater
Linux 2.6
Linux 2.6
 
Messaggi: 508
Iscritto il: sab feb 05, 2005 0:00
Località: Cagliari <---> Torino
Nome Cognome: Giuseppe M.
Slackware: Current
Kernel: 2.6.32.7-smp
Desktop: kde 4.3.4


Torna a Programmazione

Chi c’è in linea

Visitano il forum: Bing [Bot] e 1 ospite