#include #include #include #include #include #include /* Programma per l'implementazione di un automa che riconosce i numeri in notazione scientifica normalizzata */ /* Il file con le stringhe di test č Test1.txt */ /* La matrice di transizione dell'automa č: | A B C D E G H S ---------------------- 0 | D G G G B 1-9 | C D G G G C e, E | E E . | D +, - | H A ---------------------- */ #define MAX_LUNGHEZZA 100 /* č la lunghezza massima di una linea di testo */ int main(int argc, char* argv[]) { /* arg c e argv funzioni di libreria che servono per inserire parametri variabili. In particolare consentono di inserire come parametro di esecuzione, il nome del file che conterrā le stringhe da controllare */ int scan(char*); /* prototipo della funzione che scandisce una stringa */ char* filename = argv[1]; /* dice che il primo parametro di esecuzione conterrā il nome del file con le stringhe. Es: la compilazione genera Scientifica.exe. Da dos lanciare: Scientifica.exe StringheTest.txt */ char buffer[MAX_LUNGHEZZA+1]; /* ogni stringa letta dal file, viene memorizzata in un buffer */ FILE* filePtr; /* puntatore al file */ filePtr = fopen(filename,"r"); if (filePtr == NULL) { /* filePtr = Null --> file non trovato */ printf("File inesistente\n"); return EOF; } while (!feof(filePtr)) { if (fgets(buffer,MAX_LUNGHEZZA,filePtr)) /* se la lettura della stringa dal file č andata a buon fine */ if (scan(buffer)) /* se la scansione della stringa ha portato al riconoscimento, ossia scan ha restituito un valore != 0 */ printf("%s riconosciuto\n", buffer); else /* la stringa non č stata riconosciuta, ossia scan ha restituito 0 */ printf("%s non riconosciuto\n",buffer); } fclose(filePtr); /* chiusura del file */ system("PAUSE"); return 0; } int scan(char* s) { /* scan prende in input una stringa e restituisce 0 se non riconosce la stringa, un valore diverso da 0 se la riconosce */ enum {S,A,B,C,D,E,G,H,POZZA} stato_corrente = S; /* stati di transizione possibili dell'automa */ int i = 0; /* serve per scandire i caratteri della stringa */ while ((s[i] != '\0' && s[i] != '\n') && stato_corrente != POZZA){ /* esco dal ciclo quando la stringa č finita (per fine stringa o fine linea) o quando lo stato corrente č uno stato pozza */ switch (stato_corrente) { case S: /* stato iniziale. La lettura di 0, una cifra, +, -, possono portare al riconoscimento. Lo 0 porta direttamente allo stato finale B */ if (s[i] == '+' || s[i] == '-') stato_corrente = A; else if (s[i] == '0') stato_corrente = B; else if (isdigit(s[i])) stato_corrente = C; else /* ho letto un carattere diverso da quelli che potevano portare al riconoscimento */ stato_corrente = POZZA; break; case A: /* devo leggere una cifra, per sperare di arrivare in uno stato finale */ if (isdigit(s[i])) stato_corrente = C; else stato_corrente = POZZA; break; case B: /* B č stato finale e duque ogni input sullo stato B, porta allo stato pozza. Es: 05 o 0. non sono riconosciuti */ case C: /* devo leggere un '.' o 'e' o 'E' per sperare di arrivare in uno stato finale */ if (s[i] == '.') stato_corrente = D; else if (s[i] == 'e' || s[i] == 'E') stato_corrente = E; else stato_corrente = POZZA; break; case D: /* devo leggere una cifra o 'e' o 'E' per sperare di arrivare in uno stato finale */ if (isdigit(s[i])) stato_corrente = D; else if (s[i] == 'e' || s[i] == 'E') stato_corrente = E; else stato_corrente = POZZA; break; case E: /* devo leggere + o - o una cifra per sperare di arrivare in uno stato finale */ if (s[i] == '+' || s[i] == '-') stato_corrente = H; else if (isdigit(s[i])) stato_corrente = G; else stato_corrente = POZZA; break; case H: /* devo leggere una cifra per sperare di arrivare in uno stato finale */ if (isdigit(s[i])) stato_corrente = G; else stato_corrente = POZZA; break; case G: /* devo leggere una cifra per rimanere in G, che č stato finale */ if (isdigit(s[i])) stato_corrente = G; else stato_corrente = POZZA; break; } i++; } if (stato_corrente == B || stato_corrente == G) /* B e G sono gli stati finali */ return !0; else return 0; }