Newsgroup: it.comp.lang.c
Titolo: AIUTO!!!!

Nessuno ha trovato una risposta al msg "Problemi con i record 2" ?
Aiutatemi...sono disperato
Grazie

sirialkiller wrote:

+---------+-----------+---------+-----------+---------+-----------+
| fldDm_1 | fld 1 ... | fldDm_2 | fld 2 ... | fldDm_3 | fld 3 ... |
Rec 1
+---------+-----------+---------+-----------+---------+-----------+
.
.
.
+---------+-----------+---------+-----------+---------+-----------+
| fldDm_1 | fld 1 ... | fldDm_2 | fld 2 ... | fldDm_3 | fld 3 ... |
Rec n
+---------+-----------+---------+-----------+---------+-----------+
                ^                     ^                     ^
  1 byte        |        1 byte       |        1 byte       |
                |                     |                     |
          fieldDim_1 byte       fieldDim_2 byte       fieldDim_1 byte
/*
  Programma per leggere un file con la struttuta riportata sopra.
  Nota: Non viene effettuato nessun controllo sulla la correttezza
        dei record letti, pertanto un record malformato fa partire
        per la tangente processBuffer().
*/
// ###################################################################
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define READBUFF_DIM 4096
#define FALSE 0
#define TRUE !FALSE
typedef struct record
{
   unsigned char priority;
   unsigned int  code;
   char          info[31];
} Record;
int processBuffer(int, char*);
int addAndSort(Record*);
int main(int argc, char* argv[])
{
   int   nRead    = 0;
   FILE* inFileP  = NULL;
   char readBuff[READBUFF_DIM] = {'\0'};
   if(2 > argc)
   {
      printf("Uso: %s inputFile\n", argv[0]);
      return 1;
   }
   inFileP = fopen(argv[1], "rb");
   if(NULL == inFileP)
   {
      printf("Impossibile aprire %s\n", argv[1]);
      return 1;
   }
   while(0 < (nRead = fread(readBuff, 1, READBUFF_DIM, inFileP)))
   {
      processBuffer(nRead, readBuff);
   }
   return 0;
}
int processBuffer
(
   int    pBuffChars,
   char*  pBuffP
)
{
   static int     restChars   = 0;     // caratteri rimasti
                                       // dall'elaborazione precedente
          int     loop        = TRUE;
          int     procChars   = 0;     // Caratteri processati
          int     nFieldChars = 0;     // Num. di caratteri del campo
                                       // del record
          char*   endP        = NULL;  // Puntatore alla fine dei
                                       // caratteri da processare
          char*   startP      = NULL;  // Puntatore all'inizio dei
                                       // caratteri da processare
          Record* recP        = NULL;  // Risultato dell'elaborazione
          char    procBuff[44] = {'\0'}; // Buffer per l'elaborazione
                                         // corrente.
          char    tmpBuff[10]  = {'\0'}; // Buffer utilizzato per la
                                         // conversione dei carat_
                                         // teri in interi
   static char    restBuff[READBUFF_DIM +44] = {'\0'};
   strncpy(restBuff +restChars, pBuffP, pBuffChars);
   startP = restBuff;
   loop = TRUE;
   while(TRUE == loop && pBuffChars +restChars > procChars)
   {
      recP = (Record*)calloc(1, sizeof(Record));
      if(NULL != recP)
      {
      // Estrazione del campo info
      // -------------------------
         nFieldChars = (unsigned char)(*startP);
         if(pBuffChars +restChars > procChars +nFieldChars +1)
         {
            endP = startP +nFieldChars +1;
            strncpy(recP->info, startP +1, nFieldChars);
            recP->info[nFieldChars] = '\0';
            procChars += endP-startP;
         // Estrazione del campo code
         // -------------------------
            startP = endP;
            nFieldChars = (unsigned char)(*startP);
            if(pBuffChars +restChars > procChars +nFieldChars +1)
            {
               endP = startP +nFieldChars +1;
               strncpy(tmpBuff, startP +1, nFieldChars);
               tmpBuff[nFieldChars] = '\0';
               recP->code = atoi(tmpBuff);
               procChars += endP-startP;
            // Estrazione del campo priority
            // -----------------------------
               startP = endP;
               nFieldChars = (unsigned char)(*startP);
               if(pBuffChars +restChars >= procChars +nFieldChars +1)
               {
                  endP = startP +nFieldChars +1;
                  strncpy(tmpBuff, startP +1, nFieldChars);
                  tmpBuff[nFieldChars] = '\0';
                  recP->priority = atoi(tmpBuff);
                  procChars += endP-startP;
                  startP = endP;
                  addAndSort(recP);
               }
               else
               {
                  restBuff[0] = strlen(recP->info);
                  sprintf(restBuff +1, "%s", recP->info);
                  strncpy(restBuff +1 +restBuff[0], startP+1,
                          (restBuff +pBuffChars +restChars) -startP);
                  free(recP);
                  restChars = 1 +restBuff[0]
                              +(restBuff +pBuffChars +restChars)
-startP;
                  loop = FALSE;
               }
            }
            else
            {
               restBuff[0] = strlen(recP->info);
               sprintf(restBuff +1, "%s", recP->info);
               strncpy(restBuff +1 +restBuff[0], startP,
                       (restBuff +pBuffChars +restChars) -startP);
               free(recP);
               restChars = 1 +restBuff[0]
                           +(restBuff +pBuffChars +restChars) -startP;
               loop = FALSE;
            }
         }
         else
         {
            restBuff[0] = nFieldChars;
            strncpy(restBuff +1, startP+1,
                     (restBuff +pBuffChars +restChars) -startP);
            restChars = (restBuff +pBuffChars +restChars) -startP;
            loop = FALSE;
         }
      }
      else
      {
        printf("Errore di allocazione memoria. Termine programma.\n");
        exit(1);
      }
   }
   return 0;
}
/*
   Io ho usato questa funzione per testare quanto estratto dal file.
   Visto che hai intenzione di ordinare i record qui va aggiunto il
   codice di sort.
*/
int addAndSort
(
   Record* pRecP
)
{
   int retVal = 0;
   if(NULL != pRecP)
   {
      retVal = printf("%d;\n%d;\n%s\n\n",
                      pRecP->priority, pRecP->code, pRecP->info);
   }
   else
      return -1;
   return retVal;
}
// ###################################################################
La soluzione proposta non e' l'unica e non e' detto che sia la migliore,
ma funziona.
Anche se il codice e' corretto (almeno con i test che ho fatto) non e'
robusto, come detto nella nota se i record sono malformati il programma
puo' scoppiare (e questo non e' bello).
Il minimo di controlli da effettuare sono:
- dopo il byte della dimensione del campo info verificare che i
caratteri
  siano tutti alfanumerici;
- dopo il byte di dimensione dei campi code e priority verificare che i
  caratteri siano compresi tra 0 e 9;
- in caso di errore decidere come terminare il programma.
Spero di esserti stato utile (e che il codice sia comprensibile).
C:\>iao Angelo.