View Full Version : [c] aiuto I/O file
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
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.
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
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.
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..
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);
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
L'errore è altrove...hai messo da qualche parte l'istruzione clear che non è un istruzione valida.
il fatto è che questo clear non c'è..
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...
si lo so ma era già stato levato..
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");
}
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);
}
ok grazie mille cionci e grazie anche a tutti gli altri siete dei grandi!!
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().
Sì, vero, si può controllare anche il valore di ritorno di fread che deve essere pari al terzo parametro :doh:
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();
}
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...
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..
ok.. chiedo scusa per la :sofico: cavolata che ho detto.. :doh:
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.