Newsgroup: it.comp.lang.c
Titolo: Lettura scrittura su file

Mi permetto di allegare il codice sorgente di un programma che sembra essere
corretto ma invece non lo è affatto.
Il programma deve analizzare dei report contenenti statistiche di accesso ad
un sito. Vengono utilizzate delle strutture "macchina" con nome (nome di
dominio o indirizzo IP) e accessi. I dati vengono memorizzati in un file
direttamente come strutture.
Il problema è dato dalla funzione che si occupa dell'inserimento di elementi
nel file. Se esiste già una struttura  che identifica la stessa macchina, i
dati devono essere aggiornati, altrimenti i dati della macchina vengono
inseriti alla fine del file.
Riporto il codice sorgente di seguito, corredato da un minimo di commento e
con variabili di controllo che possano facilitare la comprensione del
comportamento del software.
Ho utilizzato la funzione "getch" che non è standard, ma presente nel
compilatore Borland Turbo C++ 1.0. E' sempre comunque possibile sostituirla
con getchar() o fgetc(stdin).
____________________________________________________________________
#include <stdio.h>
#define LUNSTR_MACC 30
struct _macchina {
 unsigned char nome[LUNSTR_MACC];
 unsigned long accessi;
};
typedef struct _macchina macchina;
int inserisci_macchina(FILE *fp, macchina m);
int main()
{
 FILE *out;
 macchina lista[10], comodo;
 char i, ch;
 /* Inizializzazione input */
 strcpy(lista[0].nome,"
volftp.tin.it
");
 lista[0].accessi = 10;
 strcpy(lista[1].nome,"
www.tin.it
");
 lista[1].accessi = 10;
 strcpy(lista[2].nome,"
www.iol.it
");
 lista[2].accessi = 10;
 strcpy(lista[3].nome,"
www.tin.it
");
 lista[3].accessi = 10;
 strcpy(lista[4].nome,"
www.pippo.it
");
 lista[5].accessi = 10;
 strcpy(lista[5].nome,"
www.tin.it
");
 lista[6].accessi = 10;
 strcpy(lista[6].nome,"
www.tin.it
");
 lista[4].accessi = 10;
 /****/
 out = fopen("prova01.txt","wb+");
 for( i=0; i<7; i++) {
  printf("\nInserisco elemento %d. Nome: %s. Accessi:
%ld.\n",i,lista[i].nome,lista[i].accessi);
  inserisci_macchina(out,lista[i]);
  getch();
 }
 rewind(out);
 puts("\n\tINIZIO LETTURA");
 fread(&comodo,sizeof(macchina),1,out);
 while(!feof(out)) {
  printf("Nome: %s\tAccessi: %ld\n",comodo.nome,comodo.accessi);
  fread(&comodo,sizeof(macchina),1,out);
  ch = getch();
  if(ch == 'q') exit(1); /*per evitare loop infinito*/
 }
 return;
}
int inserisci_macchina(FILE *fp, macchina m)
{
 macchina comodo;
 unsigned char ch=0;
 long i;
 printf("Chiamata funzione con valori %s %ld.\n",m.nome,m.accessi);
 rewind(fp);
 i = ftell(fp); /*leggo la posizione dell'elemento che vado a leggere*/
 fread(&comodo,sizeof(macchina),1,fp); /*leggo il primo elemento*/
 while(!feof(fp)) {
  printf("Confronto %s con %s. (Letto alla posizone:
%d)\n",m.nome,comodo.nome,i);
  if(!strcmp(comodo.nome,m.nome)) break;
  i = ftell(fp);
  fread(&comodo,sizeof(macchina),1,fp);
  ch = getch();
  if(ch == 'q') return 1; /* per evitare loop infinito*/
 }
 if(feof(fp)) { /*il file Š vuoto o non sono stati trovati elementi da
aggiornare*/
  fseek(fp,0,SEEK_END);
                i = ftell(fp);
  printf("Aggiungo nuovi dati alla posizione: %d\n",i);
 }
 else {  /*trovato elemento da aggiornare*/
  m.accessi += comodo.accessi;
  fseek(fp,-sizeof(macchina),SEEK_CUR);
  i = ftell(fp);
  printf("Aggiorno dati esistenti alla posizione: %d\n",i);
 }
 fwrite(&m,sizeof(macchina),1,fp); /*scrivo dati*/
 return 0;
}
___________________________________________________________________
Il problema si ha nell'inserimento della struttura relativa a
"
www.pippo.it
". L'errore non è dovuto al particolare elemento dell'array, ma
proprio al valore "
www.pippo.it
", poiché spostandolo all'interno dell'array
si blocca sempre allo stesso valore. Per "blocca" intendo che non viene
riconosciuta più la fine del file.
Ringrazio in anticipo chiunque voglia dedicarmi tempo.
--
Francesco Trotta
http://space.tin.it/computer/ftrotta
Elimina "x_" dal mio indirizzo per mandarmi
un messaggio direttamente

   printf("Confronto %s con %s. (Letto alla posizone: %d)\n",m.nome,comodo.nome,i);
Qui e in tutte le printf successive ci vuole
printf("Confronto %s con %s. (Letto alla posizone:
%ld)\n",m.nome,comodo.nome,i);
Comunque, compilato con il DJGPP, funziona perfettamente.
EMG