View Single Post
Old 11-03-2013, 12:47   #4
Vincenzo1968
Bannato
 
Iscritto dal: Mar 2008
Cittā: Villabate(PA)
Messaggi: 2515
Improved version con automa a stati:

Codice:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <time.h>
#include <stdint.h>

typedef enum tagStates
{
	S0,
	S1,
	S2,
	S3
} States;

typedef struct tagPersona
{
	unsigned char *Nome;
	struct tagPersona *next;
	struct tagPersona *last;	
} Persona;

void Print(Persona *first)
{
	Persona *n = first;

	printf("\n");
	while( n != NULL )
	{
		printf("%s\n", n->Nome);
		n = n->next;
	}
}

void FreeList(Persona *first)
{
	Persona *n1 = first, *n2;
	while ( n1 != NULL )
	{
		n2 = n1->next;
		if ( n1->Nome )
			free(n1->Nome);
		free(n1);
		n1 = n2;
	}
}

Persona* NewNode(Persona *Pers)
{
	Persona *n;
	size_t len;
	
	len = strlen(Pers->Nome);

	n = (Persona *)malloc(sizeof(Persona));
	if( n == NULL )
	{
		printf("\nNewNode 1: Impossibile allocare la memoria. LOL!!!\n");
		return NULL;		
	}		
		
	n->Nome = (unsigned char*)malloc(sizeof(unsigned char) * len + 1);
	if ( !n->Nome )
	{
		printf("\nNewNode 2: Impossibile allocare la memoria. LOL!!!\n");		
		free(n);
		n = NULL;
		return NULL;		
	}	

	strcpy(n->Nome, Pers->Nome);
	n->next = NULL;

	return n;
}

Persona* Append(Persona *Pers, Persona *first)
{
	Persona *n = first, *nuovo;

	if ( first == NULL )
	{
		nuovo = NewNode(Pers);
		if ( !nuovo )
			return first;
		nuovo->last = nuovo;
		return nuovo;		
	}

	nuovo = NewNode(Pers);
	if ( !nuovo )
		return first;
	n = first->last;
	n->next = nuovo;
	first->last = n->next;

	return first;
}

uint64_t MakeBuffer(const char *szFileName, unsigned char **buffer)
{
	long x;
	uint64_t retSizeData = 0;
	long numread;
	FILE *fp;
	
	fp = fopen(szFileName, "rb");
	if ( fp == NULL )
	{
		printf("\nLOL!!!\nErrore nell'apertura del file \"%s\". Addio!\n", szFileName);
		return 0;
	}
	
#if __linux__ || __APPLE__	
	fseeko(fp, 0, SEEK_END);
	retSizeData = ftello(fp);
	fseeko(fp, 0, SEEK_SET);
#else
	_fseeki64(fp, 0, SEEK_END);
	retSizeData = _ftelli64(fp);
	_fseeki64(fp, 0, SEEK_SET);	
#endif

	*buffer = (unsigned char *)malloc(sizeof(unsigned char) * retSizeData);
	if ( !*buffer )
	{
		printf("\nLOL!!!\nMemoria insufficiente. Addio!\n");
		fclose(fp);
		return 0;	
	}
		
	numread = fread(*buffer, 1, retSizeData, fp);
	if ( numread < retSizeData )
	{
		fclose(fp);
		free(*buffer);
		*buffer = NULL;
		printf("\nLOL!!!\nErrore nella lettura del file %s\n", szFileName);
		return 0;
	}
	
	fclose(fp);
	
	return retSizeData;
}

int DFA(unsigned char *buffer, uint64_t SizeData, Persona **pPers)
{
	States state = S0;	
	char c;
	long k;
	long x;	
	Persona Pers;
	
	Pers.Nome = (unsigned char*)malloc(sizeof(unsigned char) * 1024);
	if ( !(Pers.Nome) )
	{
		printf("Impossibile allocare la memoria. LOL!!!\n");
		return 0;		
	}		

	x = 0;
	k = 0;
	while ( k < SizeData )
	{
		c = *(buffer + k++);
		
		while ( c == ' ' || c == '\t' || c == '\n' || c == '\r' )
		{
			c = *(buffer + k++);	
			if ( k >= SizeData )
			{
				free(Pers.Nome);
				return k;
			}
		}
		
		switch( state )
		{
			case S0:
				x = 0;
				if ( c == '"' )
				{
					state = S1;
				}
				else
				{
					printf("\nS0 Errore: %c input malformato. Addio!\n", c);
					free(Pers.Nome);
					return 0;
				}
				break;
			case S1:
				if ( (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= 128 && c <= 154) || (c >= 224 && c <= 237) )
				{
					Pers.Nome[x++] = c;	
					if ( x >= 1024 )
					{
						printf("\nS1 LOOOOOOLLL!!! Ho trovato un nome piu' lungo di 1024 caratteri. LOOOOOOLLL!!! Addio!\n");
						free(Pers.Nome);
						return 0;
					}																		
				}
				else
				{
					k--;
					state = S2;
				}
				break;
			case S2:
				if ( c == '"' )
				{
					Pers.Nome[x] = '\0';
					x = 0;
					*pPers = Append(&Pers, *pPers);
					state = S3;
				}
				else
				{
					printf("\nS2 Errore: %c input malformato. Addio!\n", c);
					free(Pers.Nome);
					return 0;										
				}
				break;
			case S3:
				if ( c == ',' )
				{
					state = S0;
				}
				else
				{
					printf("\nS3 Errore: %c input malformato. Addio!\n", c);
					free(Pers.Nome);
					return 0;															
				}
				break;
			default:
				printf("\nLOL! Errore: %c input malformato. Addio!\n", c);
				free(Pers.Nome);
				return 0;
		}		
	} 

	if ( Pers.Nome )
		free(Pers.Nome);

	return k;
}

int main(int argc, char* argv[])
{
	Persona *pPers = NULL;
	unsigned char *buffer = NULL;
	uint64_t sizeData = 0;
	int ret;

	if ( argc != 2 )
	{
		printf("\nDevi specificare il nome di un file!\n");
		printf("\nUso: %s nomefile\n\n", argv[0]);
		return -1;
	}
	
	sizeData = MakeBuffer(argv[1], &buffer);
	if ( !sizeData )
	{
		printf("\nImpossibile allocare il buffer. Addio!\n");
		return -1;
	}
	
	ret = DFA(buffer, sizeData, &pPers);

	printf("\n");
	
	if ( ret && pPers )
		Print(pPers);
		
	printf("\n");
	
	if ( pPers)
		FreeList(pPers);
	
	if ( buffer )
		free(buffer);

	return 0;
}





Ultima modifica di Vincenzo1968 : 11-03-2013 alle 13:03.
Vincenzo1968 č offline   Rispondi citando il messaggio o parte di esso