Newsgroup: it.comp.lang.c
Titolo: problema serio

Ok, cercherò di essere breve e conciso!
Ho l'esigenza di leggere un file e per far ciò imposto un buffer grande a
piacere (meglio piccolo a piacere!).
Ora inizio a leggere la 1° stringa del file e la metto dentro il buffer.
Controllo il buffer per verificare che la stringa sia stata letta tutta, per
far ciò vedrò se alla fine del buffer esiste un '\n' o '\0' , ma visto che
apro il file in binario cercherò '\n'.
Se nel buffer c'è tutta la stringa, la copierò dentro un array dinamico che
userò più avanti per alcune verifiche..
Se nel buffer non trovo la fine della stringa, perchè questa è
particolarmente lunga, allora dovrò continuare a leggere la stringa dal file
aggiungendola al buffer per poi ricostruire la stringa completa più avanti.
Ora il problema è tradurre il concetto di buffer come l'ho descritto sopra
in linuaggio C.
Grazie a chiunque possa darmi una mano.


wrote:


Questo è ovvio, ma dato che sto trovando molte difficoltà nell'acquistare un
testo sul C, mi arrangio come posso, chiedendo aiuto ai ns e studiandomi
l'help del visual C (in inglese) ed ho già fatto molto con quello, ma non si
può fare tutto!!


wrote:

Io comincierei con il distinguere due sottoproblemi:
1) salvare un numero arbitrario di linee allocate dinamicamente
2) leggere linee arbitrariamente lunghe
Per la soluzione del primo problema si potrebbe usare
qualcosa di simile al codice seguente:
/************ INIZIO CODICE ************/
char **lines;    /* Array di puntatori alle righe */
int lines_size;  /* Dimensione attuale dell'array */
int lines_n;     /* Numero di spazi usati nell'array */
/*
** Aggiunge una linea al vettore di stringhe.
** Aumenta la dimensione del vettore nel caso
** che non ci sia piu' spazio.
*/
void AddLine(char *s)
{
  if (lines_n==lines_size)
  {
    int new_lines_size=lines_size*2+100;
    char **new_lines=Malloc(new_lines_size*sizeof(char *));
    if (lines)
    {
      memcpy(new_lines,lines,lines_size*sizeof(char *));
      Free(lines);
    }
    lines=new_lines; lines_size=new_lines_size;
  }
  lines[lines_n]=Malloc(1+strlen(s));
  strcpy(lines[lines_n],s);
  lines_n++;
}
/******************* FINE CODICE *******************/
La funzione mantiene un vettore di puntatori a carattere;
questo vettore viene ridimensionato copiando i dati
ogni qualvolta si arriva al suo riempimento.
Nota che la quantita' di memoria in gioco e' tutto
sommato limitata visto che solo i puntatori devono
essere copiati.
Nel caso che ti fossi posto la domanda le funzioni
void *Malloc(int size) e void Free(void *p) sono due
"rimpiazzi" che uso spesso al posto di malloc e free
per una serie di ragioni che non mi dilungo a spiegare.
In ogni caso Malloc non torna mai NULL (il programma
viene semplicemente interrotto in caso di esaurimento
della memoria disponibile).
Il secondo problema e' abbastanza simile:
/************ INIZIO CODICE ************/
/*
** Accoda il contenuto di un file al vettore
*/
void AddFile(FILE *f)
{
  char *buf;     /* Buffer temporaneo di linea */
  int bufsize;   /* Dimensione corrente del buffer */
  int sz;        /* Numero di caratteri nel buffer */
  int c;         /* Carattere corrente */
  buf=NULL; bufsize=sz=0;
  while ((c=fgetc(f))!=EOF)
  {
    if (sz==bufsize)
    {
      /* Espande buffer di lavoro */
      int new_bufsize=bufsize*2+100;
      char *new_buf=Malloc(new_bufsize);
      if (buf)
      {
        memcpy(new_buf,buf,bufsize);
        Free(buf);
      }
      buf=new_buf; bufsize=new_bufsize;
    }
    if (c=='\n')
    {
      /* Aggiunge linea al vettore */
      buf[sz]='\0'; AddLine(buf);
 
      sz=0; /* Riparte da inizio buffer */
    }
    else
    {
      /* Memorizza carattere e prosegue */
      buf[sz++]=c;
    }
  }
  if (sz)
  {
    /* Aggiunge ultima linea al vettore */
    buf[sz]='\0'; AddLine(buf);
  }
 
  /* Dealloca area di lavoro */
  if (buf)
    Free(buf);
}
/******************* FINE CODICE *******************/
Se hai dubbi sul codice fammi sapere.
Andrea
--
Andrea Griffini, Programmer
http://www.netservers.com/~agriff