Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
C/C++ - Problema di allocazione in un parser
Forum - C/C++ - Problema di allocazione in un parser

Avatar
TheWorm (Member)
Rookie


Messaggi: 24
Iscritto: 13/09/2009

Segnala al moderatore
Postato alle 20:04
Sabato, 18/09/2010
Ciao a tutti, scusate il titolo poco descrittivo ma non sapevo che scrivere: il mio problema è effettivamente riguardante l'allocazione e il salvataggio di dati in un semplice parser che ho scritto. Almeno credo.

Il programma legge del testo in STDIN, lo divide in token di due tipi (parole o caratteri non alfabetici) che vengono salvati in un array di token.
Non capisco dove sbaglio, eppure quando il programma prova a stampare i token salvati, alla fine del processo, stampa qualcosa di strano e si capisce che qualcosa è andato storto...
Scusate i pochi commenti, spero che il codice sia leggibile ugualmente.

Aspetto l'eroe che di darà qualche suggerimento... grazie! :k:

Oltre a qui sotto, il codice lo trovate a http://sprunge.us/NWHQ?c.

Codice sorgente - presumibilmente C++

  1. /*
  2. *  This program reads from STDIN an arbitrary text which will be tokenized.
  3. *  A token can be either a word or another non-alphabetic character.
  4. *
  5. *  When it finds a '0xFF' char it will parse the seguent char as it was the
  6. *  number of repetitions of the following third char:
  7. *  "Hi everyb0xFF0x390dy"  --->  "Hi everybooooooooody"
  8. */
  9.  
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <ctype.h>
  13.  
  14. #define WORD    1
  15. #define PUNCT   2
  16.  
  17. /* function declarations */
  18. void parse(int);
  19. void got_token(int);
  20. void add_to_token(int);
  21. void close_token(void);
  22.  
  23. unsigned int words = 0,         /* amount of words read from the input text */
  24.              puncts = 0,        /* amount of punctuation characters, including spaces, etc. */
  25.              token_num = 0,     /* will be the sum of words + puncts */
  26.              length = 0;        /* the length of a token in chars (temporary var) */
  27.  
  28. /* pointer to an area of memory containing pointers to tokens */
  29. int **array_token;
  30.  
  31.  
  32.  
  33. int main(void) {
  34.     int c, len;
  35.     array_token = malloc(sizeof(int *));
  36.  
  37.     /* decompress/read and store STDIN in tokens */
  38.     while (1) {
  39.         c = getchar();
  40.         if (c == EOF) {
  41.             parse(c);
  42.             break;
  43.         }
  44.         if (c == 0xFF) {
  45.             len = getchar();
  46.             c = getchar();
  47.             while (len--)
  48.                 parse(c);
  49.         } else
  50.             parse(c);
  51.     }
  52.  
  53.     /* eventually, do something with the data... */
  54.     printf("Words:\t\t%d\n"             /* total amount of words read */
  55.             "Puncts:\t\t%d\n"           /* total amount of punctuation chars */
  56.             "Tokens:\t\t%d\n"           /* number of tokens */
  57.             "Arrays used:\t%d\n",       /* real number of arrays used */
  58.             words,
  59.             puncts,
  60.             words + puncts,
  61.             token_num + 1);
  62.  
  63.     /* DOESN't WORK: print out every token */
  64.     c = token_num;
  65.     puts("\nThese are the tokens:\n");
  66.     do {
  67.         printf("%s\n", (char *)array_token[c]);
  68.     } while (c--);
  69.  
  70.     /* free used memory!! */
  71.     do {
  72.         free(array_token[token_num]);
  73.     } while (token_num--);
  74.     free(array_token);
  75.  
  76.     return 0;
  77. }
  78.  
  79. void parse(int c) {
  80.     static enum {
  81.         START, IN_WORD
  82.     } state;
  83.  
  84.     if (c == EOF) {
  85.         if (state == IN_WORD)
  86.             words++;
  87.         else {
  88.             free(array_token[token_num]);
  89.             if (token_num > 0)
  90.                 token_num--;
  91.         }
  92.         close_token();
  93.         return;
  94.     }
  95.  
  96.     switch (state) {
  97.     case IN_WORD:
  98.         if (isalpha(c)) {
  99.             add_to_token(c);
  100.             return;
  101.         }
  102.         got_token(WORD);
  103.         state = START;
  104.         /* fall through */
  105.  
  106.     case START:
  107.         add_to_token(c);
  108.         if (isalpha(c))
  109.             state = IN_WORD;
  110.         else
  111.             got_token(PUNCT);
  112.         break;
  113.     }
  114. }
  115.  
  116. void got_token(int type) {
  117.     switch (type) {
  118.         case WORD:
  119.             words++;
  120.             break;
  121.         case PUNCT:
  122.             puncts++;
  123.             break;
  124.     }
  125.  
  126.     close_token();
  127.     array_token = realloc(array_token, (++token_num + 1) * sizeof(int *));      /* new token */
  128. }
  129.  
  130. void add_to_token(int c) {
  131.     /* We should have already inizialized array_token. Let's be safe... */
  132.     if (array_token == NULL)
  133.         array_token = malloc(sizeof(int *));
  134.  
  135.     /* inizialize the array to store the token if non-existent */
  136.     if (array_token[token_num] == NULL) {
  137.         length = 0;
  138.         array_token[token_num] = malloc(sizeof(int));
  139.         array_token[token_num][length] = c;
  140.     }
  141.     /* otherwise, expand its size in memory */
  142.     else {
  143.         array_token[token_num] = realloc(array_token[token_num], (++length + 1) * sizeof(int));
  144.         array_token[token_num][length] = c;
  145.     }
  146. }
  147.  
  148. /* this is an optional function... */
  149. void close_token() {
  150.     /* realloc the array, expanding its size, in order to add '\0' at the end */
  151.     array_token[token_num] = realloc(array_token[token_num], (++length + 1) * sizeof(int));
  152.     array_token[token_num][length] = '\0';
  153. }


Ultima modifica effettuata da TheWorm il 23/09/2010 alle 22:16
PM
Avatar
TheWorm (Member)
Rookie


Messaggi: 24
Iscritto: 13/09/2009

Up
0
Down
V
Segnala al moderatore
Postato alle 0:49
Mercoledì, 29/09/2010
Nessuno eh? Ho provato a riscrivere il codice salvando i token in una linked list.. senza successo.

... na non c'è proprio anima viva? Nessuno può aiutarmi?

PM
Avatar
TheWorm (Member)
Rookie


Messaggi: 24
Iscritto: 13/09/2009

Up
0
Down
V
Segnala al moderatore
Postato alle 19:12
Giovedì, 30/09/2010
Bah, intanto ho abbellito un po' il codice... che continua a non funzionare!
http://sprunge.us/XSbg?c

PM