PDA

View Full Version : [c] aiuto I/O file


deviato
01-04-2008, 17:47
questo è il listato:



FILE *pass

void database()
{ char selezione,ambulanza[20];
int n=0;

do
{
system("cls");

pass=fopen("ambulanze.dat","r");

if (pass==NULL) printf("Impossibile aprire il file\n\n");
else
{ do
{
fread(ambulanza,sizeof(ambulanza),1,pass);
printf("%s",ambulanza);
}while(!feof(pass));
fclose(pass);
}



printf("\nAggiungere nuove ambulanze? S/N");
scanf("%c",&selezione);

if (selezione=='s')
{

printf("Inserisci l'associazione di appartenenza: ");
scanf("%s",ambulanza);
printf("Confermi: %s? S/N",&ambulanza);
scanf("%s",&selezione);

if (selezione == 's')
{ for(n=0;n<20;n++) if (ambulanza[n]=='\0') ambulanza[n+1]='\n';
pass=fopen("ambulanze.dat","a");
if (pass==NULL) printf("impossibile aprire il file o file non presente\n\n");
else
{ fwrite(ambulanza,20,1,pass);
fclose(pass);
}
}
}
}while (selezione != 'n');
system("pause");
menu();
}

scrive tranquillamente il contenuto soltanto che non riesce a leggerlo.. se non il primo elemento.. avete la soluzione? sono ben accette modifiche al listato e company.. io utilizzo il dev-c++ su windows.
Grazie

andbin
01-04-2008, 20:32
printf("Confermi: %s? S/N",&ambulanza);
scanf("%s",&selezione);Devi usare %c, non %s (come tra l'altro hai già fatto poco prima).

Non ho capito perché devi fare questo loop:
for(n=0;n<20;n++) if (ambulanza[n]=='\0') ambulanza[n+1]='\n';

Giusto per chiarire: quello che c'è e che scrivi nel file non sono proprio solo "righe" di testo ma blocchi di 20 byte esatti. Se nell'array 'ambulanza' il testo che inserisci è più corto, dopo il nullo finale (messo da scanf) c'è sicuramente "spazzatura".

Inoltre ti segnalo, se lo accetti, che dovresti curare un pochino di più lo stile di scrittura del sorgente e mi riferisco in particolare alla indentazione.

deviato
01-04-2008, 22:48
Ok! attualmente il listato è il seguente:

void database()
{ char selezione,ambulanza[20];

do
{
system("cls");

pass=fopen("ambulanze.dat","r");

if (pass==NULL) printf("Impossibile aprire il file\n\n");
else
{ do
{
fread(ambulanza,20,1,pass);
printf("%s",ambulanza);
clear(pass);
}while(!feof(pass));
fclose(pass);
}



printf("\nAggiungere nuove ambulanze? S/N");
scanf("%c",&selezione);

if (selezione=='s')
{

printf("Inserisci l'associazione di appartenenza: ");
scanf("%s",ambulanza);
printf("Confermi: %s? S/N",&ambulanza);
scanf("%c",&selezione);

if (selezione == 's')
{ pass=fopen("ambulanze.dat","a");
if (pass==NULL) printf("impossibile aprire il file o file non presente\n\n");
else
{ fwrite(ambulanza,20,1,pass);
fclose(pass);
}
}
}
}while (selezione != 'n');
system("pause");
menu();
}

il problema purtroppo resta il medesimo.. come potrei fare per far si che quella "spazzatura" non venga registrata nel file? devo anche considerare che poi il file devo leggerlo e ciò mi comporta una lettura di un blocco prestabilito.. hai qualche soluzione da suggerirmi? si lo so la scrittura non appare molto bella.. ma sn alle prime armi e sto facendo un pochina di pratica..
Grazie

andbin
02-04-2008, 09:14
come potrei fare per far si che quella "spazzatura" non venga registrata nel file? devo anche considerare che poi il file devo leggerlo e ciò mi comporta una lettura di un blocco prestabilito..Ma non è detto ... dipende da come deve essere gestito il file. Mi spiego meglio. Usare dei "record" di lunghezza fissa è indispensabile nei casi in cui è necessario poter accedere al record i-esimo in modo "casuale" (proprio perché grazie alla lunghezza fissa del record posso calcolare l'offset). Inoltre se si usano dei "record" di lunghezza fissa tipicamente è perché si devono scrivere dei dati "binari" con una struttura ben nota e prestabilita.

Non mi sembra che sia il tuo caso. Devi scrivere stringhe testuali di lunghezza anche diversa e la lettura che fai all'inizio è di tipo "sequenziale".

hai qualche soluzione da suggerirmi?Se è come ho appena detto poco fa, allora ti conviene gestire il file a "righe" di testo, come un normale file di testo che si scrive con Notepad e simili.

Usa fgets() per leggere una riga (occhio ci sono alcune questioni da tenere presente, vedi la documentazione) e usa fprintf() per scrivere la riga sul file.

deviato
02-04-2008, 11:14
Si infatti inizialmente avevo risolto in quel modo solo che poi in un'altra funzione ho bisogno che siano salvati tutti come record distinti.. e questo mi sta creando non pochi problemi..

cionci
02-04-2008, 11:41
Se devi lavorare su un reacord salva e leggi il record intero.

Mettiamo che la struct sia questa:

struct pippo
{
char s1[20];
char s2[30];
int a;
int b;
double y;
};

per salvare l'intera struct:

struct pippo pluto;
/* al posto di questa riga pluto viene riempito con i dati */
/* scrivo nel file dopo averlo aperto ovviamente */
fwrite(&pluto, sizeof(struct pippo), 1, out);


Per leggere:
struct pippo pluto;

/*apro il file e leggo*/
fread(&pluto, sizeof(struct pippo), 1, in);

deviato
02-04-2008, 12:06
ho fatto come dicevi te.. ovviamente al posto di in e out ho messo il puntatore del mio file..
Mi è apparso il seguente errore:

[Linker error] undefined reference to `clear'
ld returned 1 exit status
C:\Documents and Settings\Alessio\Desktop\118_firenze_soccorso\Makefile.win [Build Error] [118_firenze_soccorso.exe] Error 1

cionci
02-04-2008, 12:12
L'errore è altrove...hai messo da qualche parte l'istruzione clear che non è un istruzione valida.

deviato
02-04-2008, 12:14
il fatto è che questo clear non c'è..

cionci
02-04-2008, 12:16
Mi sembra strano. Prova a fare un nuovo progetto.

wingman87
02-04-2008, 12:58
Nel secondo listato che hai postato però un clear c'è. Dentro al secondo do-while, magari non l'hai notato...

deviato
02-04-2008, 14:17
si lo so ma era già stato levato..

deviato
02-04-2008, 14:49
ho scritto questo programmino per prova.. solo che non capisco perchè l'ultimo valore inserito nel file me lo scrive per 2 volte..

#include <stdio.h>

FILE *pf;


main()
{char pluto[20];
printf("Indirizzo: ");
scanf("%s",pluto);
pf=fopen("servizi.dat","a");
if (pf==NULL) printf("Impossibile aprire il file\n\n");
else
{
fwrite(&pluto,sizeof(pluto),1,pf);
fclose(pf);
}
pf=fopen("servizi.dat","r");
if (pf==NULL) printf("Impossibile aprire il file\n\n");
else
{
do
{
fread(&pluto,sizeof(pluto),1,pf);
printf("%s\n",pluto);
}while(!feof(pf));
}
system("pause");
}

cionci
02-04-2008, 15:00
feof rileva la fine del file dopo che una lettura fallisce, quindi devi farlo così:

do
{
fread(&pluto,sizeof(pluto),1,pf);
if(!feof(pf)) printf("%s\n",pluto);
}while(!feof(pf));

Oppure:
while(1)
{
fread(&pluto,sizeof(pluto),1,pf);
if(feof(pf))
{
break;
}
printf("%s\n",pluto);
}

deviato
02-04-2008, 15:05
ok grazie mille cionci e grazie anche a tutti gli altri siete dei grandi!!

andbin
02-04-2008, 15:13
In genere basta fare:

while (fread (&pluto,sizeof(pluto),1,pf) == 1)
{
/* usa pluto */
}
Eventualmente dopo il loop si può controllare se la causa della fine del loop è stato un errore usando ferror().

cionci
02-04-2008, 15:18
Sì, vero, si può controllare anche il valore di ritorno di fread che deve essere pari al terzo parametro :doh:

deviato
02-04-2008, 15:43
ho fatto il programmino di prova e funziona.. sapete dirmi perchè qua mi scrive ma continua a non leggermi i valori nel file?

void database()
{ char selezione,ambulanza[20];

do
{
system("cls");

pass=fopen("ambulanze.dat","r");

if (pass==NULL) printf("Impossibile aprire il file\n\n");
else
{
do
{
fread(&ambulanza,sizeof(ambulanza),1,pass);
if (!feof(pass)) printf("%s\n",&ambulanza);
}while(!feof(pass));
fclose(pass);
}



printf("\nAggiungere nuove ambulanze? S/N");
scanf("%s",&selezione);

if (selezione=='s')
{

printf("Inserisci l'associazione di appartenenza: ");
scanf("%s",ambulanza);
printf("Confermi: %s? S/N",ambulanza);
scanf("%s",&selezione);

if (selezione == 's')
{
pass=fopen("ambulanze.dat","a");
if (pass==NULL) printf("Impossibile aprire il file\n\n");
else
{
fwrite(&ambulanza,sizeof(ambulanza),1,pass);
fclose(pass);
}
}
}
}while (selezione != 'n');
system("pause");
menu();
}

andbin
02-04-2008, 15:46
Aggiungo ancora un'ultimissima cosa: se si usano fread/fwrite per leggere/scrivere, come è appunto tipico, dati binari, è bene aprire il file in modalità "binaria", usando "rb", "wb" ecc...

deviato
02-04-2008, 16:24
ma la lettura di file che contengono stringe non è binario giusto? cmq ci sono degli errori? perchè scrivere mi scrive bene.. è la lettura che non va..

deviato
02-04-2008, 17:28
ok.. chiedo scusa per la :sofico: cavolata che ho detto.. :doh: