/**************************************************************************** PROGRAMA: Words AUTOR: Kiko FECHA: 19.09.94 FINALIDAD: Imprime en orden alfab‚tico las palabras contenidas en un fichero de texto. HISTORIA: BIBLIOGRAFIA: Practical C Programming Steve Oualline O'Reilly & Associates, Inc Cap. 16 Advanced Pointers pg. 271 y sigs. MODO DE UTILIZACION: words ****************************************************************************/ #include #include #include #include struct node { struct node *right; /* sub rbol derecho */ struct node *left; /* sub rbol izquierdo */ char *word; /* palabra de este nodo */ }; static struct node *root = NULL; /* La ra¡z del  rbol */ /* PROTOTIPOS DE FUNCIONES */ void scan(char *name); /* Recorre el fichero buscando palabras */ void print_tree(struct node *top); /* Imprime las palabras del fichero */ void enter(struct node **root, char *word); /* Coloca una palabra en el  rbol */ char *save_string(char *string); /* Almacena una string en el heap */ void memory_error(void); /* Indica al usuario que no hay memoria */ main(int argc, char *argv[]) { if (argc != 2) { (void) fprintf(stderr, "Error: N£mero de par metros err¢neo\n"); (void) fprintf(stderr, " en la l¡nea de comandos\n"); (void) fprintf(stderr, "El modo de uso es:\n"); (void) fprintf(stderr, " words 'fichero'\n"); exit(8); } scan(argv[1]); print_tree(root); return(0); } /**************************************************************************** * Scan -- recorre el fichero localizando palabras * * Par metros: * name -- nombre del fichero a recorrer ****************************************************************************/ void scan(char *name) { char word[100]; /* Palabra en curso */ int index; /* Indice dentro de la palabra */ int ch; /* Caracter actual */ FILE *in_file; /* Fichero de entrada */ in_file = fopen(name, "r"); if (in_file == NULL) { (void) fprintf(stderr, "Error: Imposible abrir %s\n", name); exit(8); } while (1) { while (1) { /* Leer ignorando los espacios en blanco */ ch = fgetc(in_file); if (isalpha(ch) || (ch == EOF)) break; } if (ch == EOF) break; word[0] = (char)ch; for (index = 1; (unsigned)index < sizeof(word); index++) { ch = fgetc(in_file); if (!isalpha(ch)) break; word[index] = (char)ch; } word[index] = '\0'; /* Terminar la palabra */ enter(&root, word); } (void)fclose(in_file); } /**************************************************************************** * Enter -- Coloca una palabra en el  rbol * * Par metros: * node -- puntero a la ra¡z del  rbol * word -- palabra a introducir ****************************************************************************/ void enter(struct node **node, char *word) { int result; /* Resultado de strcmp */ /* Mirar si se ha llegado al final */ if ((*node) == NULL) { (*node) = (struct node *)malloc(sizeof(struct node)); if ((*node) == NULL) memory_error(); (*node)->left = NULL; (*node)->right = NULL; (*node)->word = save_string(word); } result = strcmp((*node)->word, word); if (result == 0) return; if (result < 0) enter(&(*node)->right, word); else enter(&(*node)->left, word); } /**************************************************************************** * Save_string -- Almacenar una string en el heap * * Par metros: * string -- string a almacenar * * Devuelve: * puntero a la memoria alojada en el heap con la string copiada en ella. ****************************************************************************/ char *save_string(char *string) { char *new_string; /* Espacio para la string */ new_string = malloc((unsigned)(strlen(string) + 1)); if (new_string == NULL) memory_error(); (void)strcpy(new_string, string); return(new_string); } /**************************************************************************** * memory_error -- Indica al usuario que no hay memoria ****************************************************************************/ void memory_error(void) { (void)fprintf(stderr, "Error: No hay memoria suficiente.\n"); exit(8); } /**************************************************************************** * print_tree -- Imprime las palabras contenidas en el  rbol * * Par metros: * top -- La ra¡z del  rbol a procesar ****************************************************************************/ void print_tree(struct node *top) { if (top == NULL) return; /* Arbol vac¡o */ print_tree(top->left); (void)printf("%s\n", top->word); print_tree(top->right); }