Foros del Web » Programación para mayores de 30 ;) » C/C++ »

carga un texto en una lista

Estas en el tema de carga un texto en una lista en el foro de C/C++ en Foros del Web. hola buenas, estoy haciendo un programa en c++ con devc++ bien pequeño, tengo que leer un txt, de ese txt almacenarlo en una estructura de ...
  #1 (permalink)  
Antiguo 11/07/2013, 08:38
 
Fecha de Ingreso: noviembre-2010
Ubicación: chile,santiago
Mensajes: 101
Antigüedad: 13 años, 5 meses
Puntos: 1
carga un texto en una lista

hola buenas, estoy haciendo un programa en c++ con devc++ bien pequeño, tengo que leer un txt, de ese txt almacenarlo en una estructura de datos, (elegi lista) luego de cargarlo debo buscar una palabra y me debe decir cuantas veces esta escrita, tengo algunos problemas para cargar el texto en la lista, ya que cuando la imprimo solo me muestra una palabra repetida, y ahora se cae al ejecutarlo, les dejo un trozo del codigo para que puedan ayudarme porfa

Código C++:
Ver original
  1. struct listasimple
  2.  {
  3.        char *texto;
  4.        struct listasimple *sgt;
  5.  }listasimple;
  6.        
  7.  
  8.  
  9. int main()
  10. {
  11.     struct listasimple *cabecera;
  12.     struct listasimple *nuevo;
  13.     cabecera=NULL;
  14.     char dato [15000];
  15.     int contador=1;
  16.     int cantnodo;
  17.     char palabra [20];
  18.     char cadena [1280];
  19.    
  20.  
  21. // aqui paso la cadena al insert
  22.         while(contador<2000)
  23.    
  24.     {
  25.    
  26.        nuevo=(struct listasimple *)malloc(sizeof(struct listasimple));    
  27.        nuevo->sgt=cabecera;                
  28.        
  29.       // cout<<"entre dato=";
  30.        //cin>>dato;
  31.        
  32.       nuevo->texto= cadena;
  33.        //cabecera=nuevo;
  34.        nuevo=nuevo->sgt;
  35.        contador++;
  36.        }  
  37.    
  38.    
  39.  
  40.           // Abro txt con las palabras
  41.               ifstream fe("prueba.txt");
  42.        
  43.        
  44.  
  45.          // leer un texto completo
  46.       while(!fe.eof()) {
  47.       fe >> cadena;
  48.       cout << cadena << endl;
  49.      
  50.                      }
  51.       fe.close();
  52.  
  53.       cin.get();

Última edición por razpeitia; 11/07/2013 a las 08:53
  #2 (permalink)  
Antiguo 12/07/2013, 16:09
 
Fecha de Ingreso: agosto-2012
Mensajes: 601
Antigüedad: 11 años, 8 meses
Puntos: 83
Respuesta: carga un texto en una lista

Es decir: el usuario escribe una o varias palabras que se guardan en un array de struct listasimple, y luego debes leer un archivo y contar cuantas veces salen esas palabras?

O el usuario entra un texto por teclado, lo parseas y lo guardas en una lista y luego tienes un archivo a modo de diccionario y tienes que contar cuantas veces se repite alguna palabra del diccionario?

O el contenido del archivo se parsea y se guarda por palabras en el array de structs, y luego se pide una palabra al usuario y debe contarse cuantas veces está en la lista?

Es que no se entiende tu pregunta, pero eso poca gente te responde.

Saludos
vosk
  #3 (permalink)  
Antiguo 14/07/2013, 22:07
 
Fecha de Ingreso: noviembre-2010
Ubicación: chile,santiago
Mensajes: 101
Antigüedad: 13 años, 5 meses
Puntos: 1
Respuesta: carga un texto en una lista

al abrir el programa se carga un txt solo. que esta en la carpeta del main.cpp.. al cargar ese txt debo guardar el txt en una lista.. luego de guardado de buscar una palabra.. y me debe decir si esta esa palabra. y cuantas veces esta
  #4 (permalink)  
Antiguo 15/07/2013, 13:55
 
Fecha de Ingreso: agosto-2012
Mensajes: 601
Antigüedad: 11 años, 8 meses
Puntos: 83
Respuesta: carga un texto en una lista

Ok, guardas un archivo de texto en la 'cadena[1280]' y lo que quieres es separar ese texto palabra por palabra, dicho de otra forma quieres tokenizar por espacios, comas, puntos, saltos de linea y todos los signos de puntuacion que se te ocurran. Primero te redefino la estructura que guardaras en la lista:

Código C:
Ver original
  1. struct PALABRA {
  2.     char *texto;
  3.     struct tagPALABRA *siguiente;
  4. };
  5. typedef struct PALABRA PALABRA;
  6. typedef struct PALABRA *LISTA;

Ahora una vez leido el archivo tienes algo asi:

Código C:
Ver original
  1. LISTA lista;
  2. char cadena [] = "Esto es una prueba de texto, para ver como funciona esto de las listas. Otra linea de texto.";

Lo siguiente es eso de tokenizar; creas una funcion que se encargue de ello a la que le envias el texto y te retorna una LISTA con las palabras encontradas. Primero defines los caracteres por los que quieres cortar:

Código C:
Ver original
  1. #define TOKENCHARS " ,.;:"

Y ahora tokenizas:

Código C:
Ver original
  1. LISTA crea_lista(char *texto) {
  2.     LISTA lista = 0;
  3.     char *pch;
  4.  
  5.     pch = strtok(texto, TOKENCHARS);
  6.     while(pch) {
  7.        
  8.         //en pch tienes la palabra de este bucle
  9.         //aqui la guardaras en la lista
  10.        
  11.         //buscas la siguiente
  12.         pch = strtok(0, TOKENCHARS);
  13.     }
  14.  
  15.     return lista;
  16. }

Para cada while obtienes una palabra del texto 'cadena', y para cada palabra (es decir para cada pch) tienes que insertarla en la lista. Pues haces otra funcion que se encargue de ello, esta nueva funcion recibe el texto y un puntero a la lista, de forma que crea una nueva estructura PALABRA, la rellena con el texto proporcionado (que será cada pch encontrado en 'crea_lista') e inenta añadirla al final de la lista; si la lista está vacía se asigna como primer y unico elemento, si tiene elementos se busca el ultimo y se añade como siguiente de ese ultimo:

Código C:
Ver original
  1. char inserta_palabra(char *texto, LISTA *lista) {
  2.     PALABRA *palabra, *ptr;
  3.  
  4.     if(!(palabra = malloc(sizeof(PALABRA)))) {
  5.         return 0;
  6.     }
  7.  
  8.     palabra->texto = texto;//ojo con esto: solo lectura
  9.     palabra->siguiente = 0;
  10.  
  11.     if(!(ptr = *lista)) {
  12.         *lista = palabra;
  13.     }
  14.     else {
  15.         while(ptr->siguiente) {
  16.             ptr = ptr->siguiente;
  17.         }
  18.         ptr->siguiente = palabra;
  19.     }
  20.  
  21.     return 1;
  22. }

Ojo una nota: cuando asignas el texto proporcionado al texto de la palabra lo hago como solo lectura, es decir no deberas escribir encima del texto que hay en las estructuras; obviamente puedes cambiarlo y usar un char[100] y copiar el texto, o bloquear con malloc la longitud de texto necesaria, solo te propongo una idea facil.

Ahora implementas dentro de la funcion 'crea_lista' la llamada a esta funcion para cada pch que encuentras en el ciclo while:

Código C:
Ver original
  1. inserta_palabra(pch, &lista);

O ya que te propongo una funcion de insercion con control de error para memoria no disponible puedes aprovechar e implementar esta llamada:

Código C:
Ver original
  1. if(!inserta_palabra(pch, &lista)) {
  2.     elimina_lista(&lista);
  3.     break;
  4. }

Junto con la funcion de implementar la lista necesitas la que te libere la memoria bloqueada para esa lista, lo que hace es recorrer la lista, liberar la memoria bloquedad para cada nodo y finalmente asignar nulo a la lista:

Código C:
Ver original
  1. void elimina_lista(LISTA *lista) {
  2.     PALABRA *ptr, *sig;
  3.     ptr = *lista;
  4.     while(ptr) {
  5.         sig = ptr->siguiente;
  6.         free(ptr);
  7.         ptr = sig;
  8.     }
  9.     *lista = 0;
  10. }

Ya tienes la lista. Antes de seguir te intereserá comprobar si ha funcionado, debes implementar una funcion que recorra esa lista:
Código C:
Ver original
  1. void muestra_lista(LISTA lista) {
  2.     LISTA ptr;
  3.  
  4.     if(!(ptr = lista)) {
  5.         printf("Lista vacia.");
  6.     }
  7.     else {
  8.         while(ptr) {
  9.             printf("%s\n", ptr->texto);
  10.             ptr = ptr->siguiente;
  11.         }
  12.     }
  13. }

Ahora vuelves al main y haces la prueba:

Código C:
Ver original
  1. LISTA lista;
  2. char cadena [] = "Esto es una prueba de texto, para ver como funciona esto de las listas. Otra linea de texto.";
  3.  
  4. if((lista = crea_lista(cadena))) {
  5.     muestra_lista(lista);
  6.     elimina_lista(&lista);
  7. }

Lo siguiente es la funcion que busca palabras en la lista; hace lo mismo que la de mostrar las palabras pero en vez de printarlas las compara con la palabra proporcionada, en caso de colision incrementa un contador y lo retorna al final:

Código C:
Ver original
  1. int encuentra_palabra(char *texto, LISTA lista) {
  2.     LISTA ptr = lista;
  3.     int ctd = 0;
  4.  
  5.     while(ptr) {
  6.         if(!strcmp(texto, ptr->texto)) {
  7.             ctd++;
  8.         }
  9.         ptr = ptr->siguiente;
  10.     }
  11.  
  12.     return ctd;
  13. }

Para la llamada solo tienes que proporcionarle un texto y una lista sobre la que trabajar, te retornará el numero de colisiones:

Código C:
Ver original
  1. int q;
  2. q = encuentra_palabra("de", lista);

Seguramente te habras fijado en que strcmp es 'case sensitive', es decir que 'hola' es diferente de 'Hola'; algunas librerias proporcionan una strcmp insensitiva (pero que no es estandar), aqui te dejo una implementacion que encontré por ahi (perdon no recuerdo de donde la saqué, tendria que citar el autor)

Código C:
Ver original
  1. int stricmp (const char *p1, const char *p2) {
  2.   register unsigned char *s1 = (unsigned char *) p1;
  3.   register unsigned char *s2 = (unsigned char *) p2;
  4.   unsigned char c1, c2;
  5.  
  6.   do
  7.   {
  8.       c1 = (unsigned char) toupper((int)*s1++);
  9.       c2 = (unsigned char) toupper((int)*s2++);
  10.       if (c1 == '\0')
  11.       {
  12.             return c1 - c2;
  13.       }
  14.   }
  15.   while (c1 == c2);
  16.  
  17.   return c1 - c2;
  18. }

Ahora puedes implementar el buscador con ambas funciones y añadir un argumento que permita la busqueda sensitiva/insensitiva:

Código C:
Ver original
  1. int encuentra_palabra(char *texto, LISTA lista, char ci) {
  2.     LISTA ptr = lista;
  3.     int ctd = 0;
  4.  
  5.     while(ptr) {
  6.         if(ci) {
  7.             if(!stricmp(texto, ptr->texto)) {
  8.                 ctd++;
  9.             }
  10.         }
  11.         else {
  12.             if(!strcmp(texto, ptr->texto)) {
  13.                 ctd++;
  14.             }
  15.         }
  16.         ptr = ptr->siguiente;
  17.     }
  18.  
  19.     return ctd;
  20. }

En la llamada solo le indicas 0 para sensitive, o 1 para insensitive
Código C:
Ver original
  1. LISTA lista;
  2. char cadena [] = "Hola que tal hola qué TAL";
  3. int q;
  4.  
  5. if((lista = crea_lista(cadena))) {
  6.     q = encuentra_palabra("hola", lista, 0);
  7.     printf("%d\n", q);//muestra 1
  8.  
  9.     q = encuentra_palabra("hola", lista, 1);
  10.     printf("%d\n", q);//muestra 2
  11.  
  12.     elimina_lista(&lista);
  13. }


Saludos
vosk
  #5 (permalink)  
Antiguo 15/07/2013, 18:37
 
Fecha de Ingreso: noviembre-2010
Ubicación: chile,santiago
Mensajes: 101
Antigüedad: 13 años, 5 meses
Puntos: 1
Respuesta: carga un texto en una lista

oo muchas gracias, en verdad te pasaste tratare de implementar esto y te cuento como me va, muy agradecido
  #6 (permalink)  
Antiguo 15/10/2013, 15:28
 
Fecha de Ingreso: octubre-2013
Ubicación: España
Mensajes: 1
Antigüedad: 10 años, 6 meses
Puntos: 0
Respuesta: carga un texto en una lista

Hola que tal. Pues yo me encuentro con el mismo problema resolver, pero en mi caso tengo que ir introduciendo palabras y cuando detecta que se repite entonces deberia mostrar un mensaje de aviso.

Entiendo que la parte de añadir lista y rastrear es igual, pero podrias ayudarme con la estructura inicial? Muchas gracias¡,

Etiquetas: int, lista, listas, programa, struct
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 14:37.