Newsgroup: it.comp.lang.c
Titolo: Problema lettura/scrittura file

Allora, il problema č questo. Ho un programma che va a leggere un file di
testo contenente varie righe, dove ogni riga ha memorizzate delle
informazioni su una persona (nome, cognome, data di nascita, tel...).
L'organizzazione in memoria, una volta letti gli elementi del file, č di un
vettore di strutture. Una volta scansionato il file, il prog mi permette di
aggiungere/cancellare una riga con dei dati immessi da me (il tutto avviene
in memoria), dopodichč scrivo su file ed esco. Quando viene letta la data di
nascita (nel formato gg/mm/aaa), questa viene prima inserita in un vettore
di char e poi, tramite delle operazioni, mi ricavo i tre int gg, mm, aaaa.
Il fatto č che finchč il programma viene eseguito una sola volta non c'č
problema, ma dalla seconda esecuzione in poi, effettuata la scrittura finale
su file, mi trovo con le date di nascita (solo quelle) completamente
cambiate. Altro fatto strano č che se eseguo il prog ed esco subito senza
fare alcuna modifica, mi ritrovo il file di testo piů grande di due byte...
Spero di essere stato chiaro :-)
Vorrei postare il codice ma sono quasi 300 righe... Lo potrei inviare in
privato a qualcuno di voi?
Grazie mille
Daniele

Magari così risulta un pò più chiaro:
Questa è la f che legge dal file:
int carica(Persona v[])
{
   int i = 0;
   FILE *fPtr;
   if ((fPtr = fopen ("agenda.dat", "r")) != NULL)
   {
      while (!feof(fPtr))
      {
         /* Scansione del vettore di strutture. */
         fscanf (fPtr, "%s %s %s %s %s %s %d %s %s %s\n", v[i].nome,
v[i].cognome, d_nascita,   vi].tel_casa, v[i].tel_cellulare,
v[i].domicilio.via, &v[i].domicilio.n_civico, v[i].domicilio.cap,
v[i].domicilio.citta, v[i].domicilio.nazione);
         /* A partire dal vettore "d_nascita", si ricavano le tre var int
"gg", "mm", "aa". */
         v[i].
data_nascita.gg
 = 10 * (d_nascita[0] - 48) + 1 *
(d_nascita[1] - 48);
         v[i].
data_nascita.mm
 = 10 * (d_nascita[3] - 48) + 1 *
(d_nascita[4] - 48);
         v[i].data_nascita.aa = 1000 * (d_nascita[6] - 48) + 100 *
(d_nascita[7] - 48) + 10 * (d_nascita[8] - 48) + 1 * (d_nascita[9] - 48);
         i++;
      }
   }
   else
   {
      printf ("Errore nell'apertura del file!");
      getchar();
   }
   fclose(fPtr);
   return i;
}
Invece questa è la f di scrittura:
void scrivi (Persona v[])
{
   int i;
   FILE *fPtr;
   if ((fPtr = fopen("agenda.dat", "w")) != NULL)
   {
      for (i = 0; i < last; i++)
      {
         /* I vettori "nome" e "cognome" contenenti la stringa CANCELLATO,
ovviamente
         non vengono scritti nel file .dat. */
         if ((strcmp(v[i].nome, "CANCELLATO") == 0) && (strcmp(v[i].cognome,
"CANCELLATO") == 0))
         continue;
         fprintf (fPtr, "%s %s %d/%d/%d %s %s %s %d %s %s %s\n", v[i].nome,
v[i].cognome,
v[i].
data_nascita.gg
, v[i].
data_nascita.mm
, v[i].data_nascita.aa,
v[i].tel_casa, v[i].tel_cellulare,
v[i].domicilio.via, v[i].domicilio.n_civico, v[i].domicilio.cap,
v[i].domicilio.citta, v[i].domicilio.nazione);
 }
   }
   else
   {
      ("Errore durante la scittura su file!");
      getch();
   }
   fclose(fPtr);
}
Quindi, ripeto, dalla seconda esecuzione del prog in poi ( e quindi dalla
seconda scrittura...), le date di nascita vengono scritte in modo sbagliato,
con numeri totalmente differenti (anche negativi). Dove può esseere
l'errore?
Ciao e grazie
Daniele

 v[i].
data_nascita.gg
, v[i].
data_nascita.mm
, v[i].data_nascita.aa,
Qui, con quel "%d/%d/%d" stai dicendo alla fprintf di stampare i tre numeri
con il numero di cifre *MINIMO* possibile.
Se uno è nato il 25 dicembre del 1999, ti stamperà questo:
   25/12/1999
E giorno, mese, anno avranno la lunghezza che t'aspettavi.
Ma se uno è nato il 1º aprile del 1999, ti stamperà questo bel pesce
d'aprile:
   1/4/1999
Se vuoi che i tre numeri abbiano lunghezza fissa devi specificarlo, così:
   %2.2d/%2.2d/%4.4d
Comunque, non capisco lo scopo nella vita di quella variabile temporanea
"d_nascita". Il "%d" ce l'ha anche la scanf: perché non lo usi!? Basta
scrivere così:
         fscanf (fPtr, "%s %s %d / %d / %d %s %s %s %d %s %s %s\n",
                 v[i].nome, v[i].cognome,
                 &v[i].
data_nascita.gg
, &v[i].
data_nascita.mm
, &v[i].data_nascita.aa,
                 v[i].tel_casa, v[i].tel_cellulare,
                 v[i].domicilio.via,
                 &v[i].domicilio.n_civico,
                 v[i].domicilio.cap,
                 v[i].domicilio.citta,
                 v[i].domicilio.nazione);
Un ultimo appunto (forse OT, forse no): ti conviene usare una stringa anche
per il numero civico. Io, per esempio, abito al numero civico "237/2": se mi
mandi una lettera al "237" la postina la dà a mio fratello.
--
Cingar
P.S. No, non in quel senso, poverina! Fra l'altro, si sposata da poco con un
gran bel ragazzo, quindi credo che almeno per un po' di anni...
--------------------------------
Inviato via 
http://arianna.libero.it/usenet/


...ma tuo fratello ti scrive spesso al 237 ?
hi hi hi :)

 "d_nascita". Il "%d" ce l'ha anche la scanf: perché non lo usi!?
Allora, grazie innanzitutto per l'aiuto. Con la modifica da te suggerita ora
il prog funziona alla grande. Per quanto riguarda la var d_nascita, è stata
imposta dal prof e stava a noi ricavarne i tre int gg, mm, aaaa. Io non
l'avrei mai fatto di mia iniziativa...
Cmq grazie ancora per l'aiuto
Ciao!
Daniele

 hi hi hi :)
Ho omesso un'informazione fondamentale: mio fratello abita pure lui al 237,
in un altra casa... :)
--
Cingar


 l'avrei mai fatto di mia iniziativa...
Scelta decisamente bizzarra... Sarebbe il caso di chiedergli il perché.
In ogni caso, quanto ho detto sulla scanf vale comunque: invece di fare
tutto quel casino con la stringa d_nascita, puoi leggerne il contenuto con
una semplice sscanf:
    sscanf(d_nascita, "%d/%d/%d", &giorno, &mese, &anno);
C'è un'ultima cosa, importantissima, che ieri avevo dimenticato: devi sapere
che mio cugino si chiama Gian Carlo Pallalontani Disonesti e abita in via
Cavoli Amari 3, 20999 Rocca Cannuccia, Italia.
Ora, prova a immettere il nominativo di mio cugino nella tua applicazione
anagrafica e dimmi se funziona ancora a meraviglia.
Aiutino: "%s".
--
Cingar


 ha scritto nel messaggio
news:195Z223Z37Z55Y1...@usenet.libero.it...

Questa è un'altra limitazione imposta. I nomi che il prog dovrà ricevere in
input per la scrittura su file non saranno mai composti. Al limite si
potrebbero immettere come Gian_Carlo Pallalontani_Disonesti.
Ciao
Daniele


 potrebbero immettere come Gian_Carlo Pallalontani_Disonesti.
Giusto, giusto. Come insegnante non sarei un granché: cercherei di insegnare
tutto alla lezione 1.
