Newsgroup: it.comp.programmare
Titolo: Linguaggio C

Sto facendo un progetto per l'università da implementare in C ANSI.
Maledetti files.
Il mio problema è questo. Devo prendere il contenuto di un file txt
contenente autore e titolo canzone e durata e metterlo in un altro file
binario organizzato con una struttura così fatta:
struct discografia{
     char titolo[40];
     int durata;
    };
Il contenuto del file di testo è questo (in realtà contiene circa 280
canzoni):
Abba - Fernando;4.13
Abs - What You've Got;3.52
Afroman - Because I Got High;5.10
A-Ha - Stay On These Roads;4.46
A-Ha - Take On Me;3.45
Alanais Morisette - Hands Clean;4.29
Alcazar - Crying At The Discoteque;3.51
Alicia Keys - Fallin';3.17
Ecco cosa ho scritto io:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* vettore di caratteri */
struct discografia{
     char titolo[40];
     int durata;
    };
int main()
{
  FILE* ftxt;                      /* puntatore al file di testo */
  FILE* fbin;                     /* puntatore al file binario*/
  char tmp[40],                   /* stringa temporanea per formattazione
*/
  *time;                               /* punt. a char per conversione
durata   */
  struct discografia playlist,  /* Vett. di struct per memorizz. in bin */
       e[285];
  int j;
  long pos;
  int lung;
  ftxt=fopen("canzoni.txt", "r");
  fbin=fopen("canzoni.bin", "wb");
  lung=0;
  while (!feof(ftxt))
   {
    fgets(tmp,80,ftxt);                                     /* load riga
file txt in tmp */
    pos=ftell(ftxt);                                          /* controllo a
quale byte del file txt si trova il puntatore */
    lung=lung+strlen(tmp)+1;                         /* verifico quanti
caratteri ho letto finora per confrontarlo con pos */
    strtok(tmp,";");                                         /* isolamento
titolo         */
    strcpy(playlist.titolo,tmp);                       /* copia titolo nel
vettore  */
/*     Le seguenti due riga trasformano la durata da stringa nella foma m.ss
in un intero che esprime la durata della
        canzone in secondi
*/
    time=strtok(NULL,";");
    playlist.durata=(atoi(strtok(time,"."))*60) + atoi(strtok(NULL,"."));
    fwrite(&playlist,sizeof(struct discografia),1,fbin);  /*   scrivo nel
file binario   */
   }
  fclose(ftxt);
  fclose(fbin);
 / *    Ora stampo nel file binario         */
  fbin=fopen("CANZONI.BIN","rb");
  fread(&e,sizeof(struct discografia),285,fbin);
  fclose(fbin);
  for (j=0;j<285;j++)
       printf("\n%d:\n\n\n%s -- %d",j+1,e[j].titolo,e[j].durata);
  return 0;
}
Se si prova ad eseguire il tutto si vedrà che ad un certo punto la lettura
del file non va avanti e senza alcun motivo la variabile pos (ma anche un
qualunque contatore i) viene azzerato dall'esecuzione della riga:
    fgets(tmp,80,ftxt);
Insomma se lo lancio non funziona. Soprattutto con il file di testo completo
delle 280 canzoni.
Qualcuno può spiegarmi quale è il problema?


Un probabile errore si trova nella riga
	fgets(tmp,80,ftxt);
ed e' che non puoi leggere 80 byte dal file, perche' non puoi sapere con 
certezza se la dimensione di una riga nel file ftxt e' di 80 byte.
Secondo me potresti adottare un'altro metodo per implementare questo 
programama, cambiando completamente algoritmo. Ad esempio, io spesso 
utilizzo una cosa del genere:
  -Crea j di tipo long // Tiene traccia del numero della canzone corrente
  -Crea ch di tipo char
  -Crea INF, OUTF      /* Puntatori di tipo FILE *, rispettivamente al
                          file di input e di output */
  -Apri INF in lettura
  -Apri OUTF in scrittura
  -Finche' feof(INF) e' diverso da 0:
   -Leggi un byte (ch) dal file sorgente (INF)
   -Verifica se tale byte (ch) e' uguale al newline ('\n') (*)
    - Se e' vero, incrementa j
    - Se e' vero, scrivi il newline ('\n') per tre volte
   -Se non e' vero, verifica se ch e' uguale a ';'
    - Se e' vero, scrivi su OUTF la stringa " -- "
    - Ciclo infinito (while(1))
     - Leggi un byte dal file sorgente (INF)
     - Scrivi il byte su OUTF
     - Se il byte e' uguale al newline ('\n')
       - Spostati alla posizione corrente -1 nel file sorgete
       - Continua il ciclo (continue)
   -Se non e' uguale ne a '\n', ne a ';', scrivi ch su OUTF
Questo codice dovrebbe funzinare. Lascio a te l'implementazione (in 
fondo si tratta di un progetto universitario, e' compito tuo).
(*) : Nota che questa condizione si verifichera' solo una volta in
       quanto i prossimi newline letti saranno letti dopo aver letto la
       durata della canzone, e quindi nella parte centrale del mio algoritmo

 ed e' che non puoi leggere 80 byte dal file......
Sopratutto se il buffer è lungo solo 40 byte......
P.S.
Per favore il quoting !
--  
Stefano L.