PDA

Visualizza la versione completa : [C]Problemi con feof()


stgww
17-05-2008, 14:17
Ciao, sono nuovo del forum, non capisco proprio deove sia il problema in questi 3 programmi.
In partica è un'archivio di cd. Con il primo programma, carico i vari record, con il secondo li mostro e con il terzo li modifico aggiungo etc, etc..
Il problema è quando li devo mostrare, poichè sembra che mettendo feof() mi conta un record in più. Es: se ho inserito tre record, lui me ne mostra 4 copiando il 3 nel 4 :confused: .
Ecco i tre programmi:

#include <stdlib.h>
#include <stdio.h>

struct rec
{
char titolo[30], autore[30];
float durata;
};

int main()
{
struct rec cd;
int i;

FILE*list;
list=fopen("dati.bin", "w");

for(i=0;i<3;i++)
{
printf("Titolo?\n");
scanf("%s", cd.titolo);
printf("Autore?\n");
scanf("%s", cd.autore);
printf("Durata (in minuti)?\n");
scanf("%f", &cd.durata);
fwrite(&cd,sizeof(struct rec),1,list);
system("CLS");
}
fclose(list);

system("PAUSE");
return 0;
}



#include <stdlib.h>
#include <stdio.h>

struct rec
{
char titolo[30], autore[30];
float durata;
};

int main()
{
struct rec cd;
int i;
FILE*list;
list=fopen("dati.bin", "r");

for(i=0;!feof(list);i++)
{
fread(&cd,sizeof(struct rec),1,list);
printf("Titolo %s \n", cd.titolo);
printf("Autore %s \n", cd.autore);
printf("Durata:%f \n", cd.durata);

}
fclose(list);

system("PAUSE");
return 0;
}

Aggiungop anche il terzo anche se penso che il problema sia nei primi 2:

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

struct rec
{
char titolo[30], autore[30];
float durata;
};

int show_user(struct rec cd,FILE*list)
{
char titolo[30];
int i;

list=fopen("dati.bin", "r");
printf("Titolo dell'album che vuoi cercare?\n");
scanf("%s", titolo);
for(i=0;!feof(list);i++)
{
fread(&cd,sizeof(struct rec),1,list);

if((strcmp(titolo,cd.titolo))==0)
{

printf("Titolo %s \n", cd.titolo);
printf("Autore %s \n", cd.autore);
printf("Durata:%f \n", cd.durata);
}
}
fclose(list);


return 0;
}

int edit_user(struct rec cd,FILE*list)
{
char titolo[30];
int i,n;
list=fopen("dati.bin", "r+");
printf("Titolo dell'album che vuoi modificare?\n");
scanf("%s", titolo);
for(i=0;!feof(list);i++)
{
fread(&cd,sizeof(struct rec),1,list);
if(strcmp(titolo,cd.titolo)==0)
break;
}
fseek(list,i*sizeof(struct rec), SEEK_SET);
printf("Titolo?\n");
scanf("%s", cd.titolo);
printf("Autore?\n");
scanf("%s", cd.autore);
printf("Durata (in minuti)?\n");
scanf("%f", &cd.durata);
fwrite(&cd,sizeof(struct rec),1,list);
return 0;
}

int add(struct rec cd,FILE*list)
{
list=fopen("dati.bin", "a");
printf("Titolo?\n");
scanf("%s", cd.titolo);
printf("Autore?\n");
scanf("%s", cd.autore);
printf("Durata (in minuti)?\n");
scanf("%f", &cd.durata);
fwrite(&cd,sizeof(struct rec),1,list);
fclose(list);
return 0;

}

int main()
{
struct rec cd;
int i,function1;

FILE*list;
show_user(cd,list);
edit_user(cd,list);
add(cd,list);


system("PAUSE");
return 0;
}



Grazie a tutti quelli che mi potranno aiutare, martedì ho il compito e non riesco a risolvere....

MacApp
17-05-2008, 14:39
A prima vista NON controlli il valore restituito da "fopen". Ami il rischio?

stgww
17-05-2008, 14:45
Originariamente inviato da MacApp
A prima vista NON controlli il valore restituito da "fopen". Ami il rischio?
Che significa non controlli?

MacApp
17-05-2008, 14:56
Originariamente inviato da stgww
Che significa non controlli?

dalla mia documantazione della fopen:



RETURN VALUES
Upon successful completion fopen(), fdopen() and freopen() return a FILE
pointer. Otherwise, NULL is returned and the global variable errno is
set to indicate the error.


Insomma se ti restutuisce NULL e tu usi quel valore hai un bel comportamento indefinito, che vuol dire: se sei fortunato hai un bel crash dell'applicazione, altrimenti qualunque altra cosa potrebbe accadere (e generalmente non trattasi di una vincita milionaria al superenalotto).

stgww
17-05-2008, 15:07
Originariamente inviato da MacApp
dalla mia documantazione della fopen:



Insomma se ti restutuisce NULL e tu usi quel valore hai un bel comportamento indefinito, che vuol dire: se sei fortunato hai un bel crash dell'applicazione, altrimenti qualunque altra cosa potrebbe accadere (e generalmente non trattasi di una vincita milionaria al superenalotto).

Quindi, in pratica cosa dovrei fare?

MItaly
17-05-2008, 15:46
Mi pare che MacApp sia stato abbastanza chiaro... :fagiano:

FILE*list;
list=fopen("dati.bin", "w");
if(list==NULL)
{
fputs("Impossibile aprire dati.bin in scrittura.",stderr);
exit(1);
}
Lo stesso dicasi per tutti gli altri casi in cui usi la fopen.

stgww
17-05-2008, 16:02
Originariamente inviato da MItaly
Mi pare che MacApp sia stato abbastanza chiaro... :fagiano:

FILE*list;
list=fopen("dati.bin", "w");
if(list==NULL)
{
fputs("Impossibile aprire dati.bin in scrittura.",stderr);
exit(1);
}
Lo stesso dicasi per tutti gli altri casi in cui usi la fopen.
Ah, ok!
Solo che la prof non ci ha spiegato fputs, stderr...

Cmq per quell'altro problema, sai qualcosa?

MacApp
17-05-2008, 16:09
Originariamente inviato da stgww
Ah, ok!
Solo che la prof non ci ha spiegato fputs, stderr...

Cmq per quell'altro problema, sai qualcosa?

Se non controlli gli errori che vengono restituiti dalle funzioni che chiami, il comportamento indefinito, indefinibile dei tuo programmini, è pressoché garantito.

MItaly
17-05-2008, 16:12
Solo che la prof non ci ha spiegato fputs, stderr...
Sono assolutamente irrilevanti per la faccenda della gestione degli errori, potevi scrivere quella riga anche con la printf e non cambiava praticamente niente (avresti scritto su stdout invece che su stderr, ma queste sono finezze). La cosa importante è controllare i valori restituiti da funzioni che possono fallire.

mondobimbi
17-05-2008, 16:17
prova a leggere i dati così



...
while (fread(&cd, sizeof(struct rec), 1, list) > 0) {
printf("Titolo %s \n", cd.titolo);
printf("Autore %s \n", cd.autore);
printf("Durata:%f \n", cd.durata);
}
...


dovrebbe risolvere il problema
ciao
sergio

Loading