Repository 32bit  Forum
Repository 64bit  Wiki

Fscanf

Forum dedicato alla programmazione.

Moderatore: Staff

Regole del forum
1) Citare sempre la versione di Slackware usata e la versione del Kernel. Questi dati aiutano le persone che possono rispondere.
2) Specificare sempre il tipo di shell (bash, sh, csh, etc...)
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 dell'ultima regola 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 19: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 15:14

Re: Fscanf

Messaggioda Blizzard » gio feb 21, 2008 20: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 23:53
Nome Cognome: Giovanni Santostefano
Slackware: 12.2
Kernel: 2.6.27.7-smp
Desktop: Fluxbox

Re: Fscanf

Messaggioda FireEater » gio feb 21, 2008 20: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 1: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 21: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: dom mag 15, 2005 0: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 21: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: 1077
Iscritto il: sab dic 16, 2006 11:48
Località: Fra Trantor e Terminus
Slackware: 13.1 / 64 bit
Kernel: 3.3.x
Desktop: KDE 4.4.5

Re: Fscanf

Messaggioda birg81 » ven feb 22, 2008 0: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 11: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 13: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 15:14

Re: Fscanf

Messaggioda boh » ven feb 22, 2008 14: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: 745
Iscritto il: ven set 16, 2005 0:00
Località: Milano.
Slackware: 14 (x64)
Kernel: 3.2.29
Desktop: KDE 4.10.3

Re: Fscanf

Messaggioda FireEater » ven feb 22, 2008 18: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 1: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 18: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 21: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 18: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 15:14

Re: Fscanf

Messaggioda FireEater » ven feb 22, 2008 20: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 1: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 20: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 21: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 21: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: 1077
Iscritto il: sab dic 16, 2006 11: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 23: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 1: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: Nessuno e 1 ospite