[ Foro de C ]

Almacenar palabras de un fichero en un strcut en C

19-Jan-2021 18:30
Invitado (PepinoSinIgual)
1 Respuestas

Tengo el siguiente problema: Programa en c, que lea un archivo txt, almacene las palabras de ese archivo en un struct,  y ordenar los elementos alfabéticamente, ninguna palabra debe repetirse.

Esto es lo que tengo hecho

#include <stdio.h>
#include <stdlib.h>

struct registro {
char *palabra;
struct registro *Siguiente;
};

// LISTA QUE ALMACENARÁ TODOS LOS VALORES
struct registro *lista;


void agregarElemento(char *nuevaPalabra) {
struct registro *temp1, *temp2;
temp1 = (struct registro*)malloc(sizeof(struct registro));
temp1->palabra = nuevaPalabra;
temp1->Siguiente = NULL;

if (lista == NULL) {
lista = temp1;
} else {
temp2 = lista;
while (temp2->Siguiente != NULL) {
temp2 = temp2->Siguiente;
}
temp2->Siguiente = temp1;
}
}

void imprimirLista() {
if (lista == NULL) {

printf("La lista esta vacia\n");
} else {
while (lista->Siguiente != NULL) {
printf("%s\n", lista->palabra);
lista = lista->Siguiente;
}
printf("%s\n", lista->palabra);
}
}

int main() {
int i;
FILE *archivo;
char caracter[255];
archivo = fopen("archivo.txt","r");

if (archivo == NULL) {
printf("\nError de apertura del archivo. \n\n");
} else {

// ESTE SOLO ALMACENA EL ULTIMO RENGLOS
/*while(fgets(caracter, 254, archivo)) {
agregarElemento(caracter);
}*/

// ESTE SOLO ALMACENA LA ULTIMA PALABRA
/* while (fscanf(archivo, "%s\n", caracter) == 1) {
// printf("%s\n", caracter);
agregarElemento(caracter);
}*/




// MÉTODO PARA IMPRIMIR LA LISTA CON TODOS LOS ELEMENTOS, HAYA O NO HAYA
imprimirLista();
printf("finalizado");
}
fclose(archivo);
return 0;
}

Por alguna razón no estaba almacenando en la lista todas las palabras del documento txt, en una forma solo almacena varias veces el último renglón y de la otra varias veces la última palabra. Quisiera saber cuál es mi error. Además, necesito ayuda para que no se repitan las palabras y ordenarlas alfabéticamente.


21-Jan-2021 21:03
Invitado (tino)

hola pepino

- para empezar tu lista no esta inicializada y puede apuntar a cualquier lado

- usando typedef se aclara un poco el código

- parece que quieres cargar el archivo registro a registro en la lista
 para esa tarea cada vez que añades uno recorres toda la lista y añades al final
 en vez de añadir al principio y listo, más eficiente. pero lo lógico seria ir
 añadiendo de manera ordenada y ahí sí tendrías que recorrer la lista hasta que
 encuentres el sitio que le corresponde e insertar la cadena
 
 por ej si ordenas de menor a mayor:
   for(int i=0; i<tam_lista; i++)              // recorro la lista
   {
     char* palabra_lista = Obtener(i, lista);  // recojo la palabra i de la lista
     int compara = strcmp(palabra_fichero, palabra_lista); // comparo
     if(compara > 0)                           // si es mayor inserto
     {
       insertar_palabra(lista, palabra_fichero);
       break;
     }
     else
       if(!compara) break;                     // si son iguales la descarto
   }  

- al principio la lista no tendrá ningún elemento, tienes que añadir un if,
 si lista vacia añade al principio

- por otro lado no conozco ninguna palablra de 255 caracteres ajustalo un poco
 la palabra más larga en español tiene 23 carecteres

- quizás el array caracter debería llamarse cadena o palabra, sería más apropiado

- no te compliques con fgets o fscanf usa strtok y strcpy o strncpy copias la cadena
 completa y listo

faltan muchas funciones para el manejo de la lista, hecha un vistazo al video
sobre listas de makigas y te dejara las cosas mucho mas claras
https://www.makigas.es/series/estructuras-de-datos/listas-enlazadas-en-c

suerte ;-)






(No se puede continuar esta discusión porque tiene más de dos meses de antigüedad. Si tienes dudas parecidas, abre un nuevo hilo.)