Newsgroup: it.comp.lang.c
Titolo: Att. Andrea Laforgia fseek

Caro Andrea,
grazie per le precedenti risposte.
Ho ancora bisogno di Te.
Devo scrivere una funziona che ricerchi un nome in un file, usando
magari strcmp della libreria <string.h>.
Il mio file:
void inserisci(AGENDAPTR nuovo)
{
    int i=0,c;
    AGENDAPTR prima;
    FILE *fPtrAgenda=fopen("d:\\agenda\\agenda.dat","r+");
    prima=malloc(sizeof(AGENDA));
    if(prima==NULL)
       printf("Memoria insufficiente\n");   
    if(fPtrAgenda==NULL)
       printf("Il file non puo' essere aperto");
    else{   
          fseek(fPtrAgenda,i*sizeof(AGENDA),SEEK_SET);
          fread(prima,sizeof(AGENDA),1,fPtrAgenda);
          c=strcmp(nuovo->cognome,prima->cognome);
          while(c<=0){
                fseek(fPtrAgenda,++i*sizeof(AGENDA),SEEK_SET);
                fread(prima,sizeof(AGENDA),1,fPtrAgenda);
                c=strcmp(nuovo->cognome,prima->cognome);
          }
          while(!feof(fPtrAgenda)){
                fseek(fPtrAgenda,i*sizeof(AGENDA),SEEK_SET);
                fwrite(nuovo,sizeof(AGENDA),1,fPtrAgenda);
                nuovo=prima;
                fseek(fPtrAgenda,++i*sizeof(AGENDA),SEEK_SET);
                fread(prima,sizeof(AGENDA),1,fPtrAgenda);
in effetti scrive nel file ma ordina dalla A alla Z sovrascrivendo
alcuni record.
Sai dove posso trovare dei semplici file di esempio.
Grazie anticipatamente.
Sergio

          fread(prima,sizeof(AGENDA),1,fPtrAgenda);
<...>
Per sicurezza, se stai programmando sotto DOS/Windows, usa il flag "b"
nell'apertura del file.  
-- 
Andrea Laforgia
#exclude <windows.h>


Sembra di capire che tu voglia mantenere ordinato il file mediante
INSERZIONE, cioe' scrivi il nuovo record e "sposti" in avanti quelli
che lo seguono. Comunque e' facile vedere che il codice e' cannato:
prendiamo il file:
# cognome
0 FUCHI
1 MAZZI
2 PRONZI
3 XULLI
e supponiamo che nuovo stia puntantdo ad una agenda con cognome NULLI.
Allora il primo pezzo di programma dovrebbe fermarsi su i=2, con PRONZI
nella memoria puntata da prima.
Allora la fwrite scrive nuovo (cioe' NULLI) in posizione 2 e si ottiene
FUCHI MAZZI NULLI XULLI
a questo punto assegni al puntatore "nuovo" il valore del
puntatore "prima", quindi la fread successiva legge il valore XULLI 
nella zona di memoria che ora e' puntata sia da prima che da nuovo (e
hai perduto PRONZI !!).
Io penso che il tuo principale errore e' in quel nuovo=prima.
E' una copia dei puntatori, non dei valori puntati. Avresti dovuto
usare qualcosa tipo *nuovo=*prima, ma e' una operazione
da fare con attenzione perche' cambia il valore contenuto nella
zona di memoria puntatata da nuovo, cioe' cambia qualcosa nel programma
chiamante, e questo devi farlo solo se sei sicuro che non
riutilizzerai quel valore.
ciao,
g.

...

Alloco dinamicamente la memoria perchè ne avrò bisogno in seguito.
Il mio problema è creare una forchetta con due puntatori es prima e
dopo.
il nuovo record andrebbe inserito tra i due.
es 
fseek(fPtrAgenda,i*sizeof(AGENDA),SEEK_SET);
fread(prima,sizeof(AGENDA),1,fPtrAgenda);
fseek(fPtrAgenda,++i*sizeof(AGENDA),SEEK_SET);/*record successivo*/
fread(dopo,sizeof(AGENDA),1,fPtrAgenda);
c=strcmp(nuovo->cognome,prima->cognome);
while(c>0 && dopo!=NULL){
      prima=dopo;
      fseek(fPtrAgenda,++i*sizeof(AGENDA),SEEK_SET);/*ancora
successivo*/
      fread(dopo,sizeof(AGENDA),1,fPtrAgenda);
      c=strcmp(nuovo->cognome,prima->cognome);
 }
if(prima==NULL){/*stiamo sul primo record agenda vuota*/
   fseek(fPtrAgenda,i*sizeof(AGENDA),SEEK_SET);
   fwrite(nuovo,sizeof(AGENDA),SEEK_SET);
  }
else{
      while(dopo!=NULL){                
            fseek(fPtrAgenda,i*sizeof(AGENDA),SEEK_SET);
                           /*offset -> quello restituito da while
precedente*/
            fwrite(nuovo,sizeof(AGENDA),1,fPtrAgenda);
            nuovo=prima;
            prima=dopo;
            fseek(fPtrAgenda,++i*sizeof(AGENDA),SEEK_SET);/* ancora
avanti*/
            fread(dopo,sizeof(AGENDA),1,fPtrAgenda);
      }
Il compilatore mi da un messaggio di warning, perchè ho allocato in
una funzione (void), un nodo della structure.
Inoltre, non mi fa il confronto con la costante NULL.
Credo che questo sia il vero problema.
Si può fare un confronto tra un record inserito in un nodo allocato
dinamicamente e la costante NULL?
Io creado di si.
Grazie Andrea.
Sergio