Estás en: Inicio >> Foros >> Informática >> Programación
Programación /

Lista abierta con Tokens de STRTOK

Participa en el tema Lista abierta con Tokens de STRTOK en el foro Programación.
Mi programa abre un archivo de texto, lee linea en linea, separa las palabras por ...

Buscar en este tema:
 
  •  
    #1 Lista abierta con Tokens de STRTOK
    Mi programa abre un archivo de texto, lee linea en linea, separa las palabras por delimitadores y todo perfecto.

    ahora bien las quiero almacenar en una lista abierta, pero sucede que guarda correctamente la primer linea, pero a partir de la segunda linea solo guarda porciones de texto y no la palabra completa.

    Dato: si le envio manualmente datos a la lista abierta addPalabra(&lista,"palabra1")... addPalabra(&lista,"palabraN") las alamacena y las puedo recorrer perfectamente.

    Problema: pero al mandarle las palabras separadas que envia el STRTOK llegan bien a la funcion y luego las almacena correctamente en el nodo nuevo->palabra pero algo mas sucede que es lo que hace que se parta las palabras al almacenarlas en la lista. :?:

    Alguien q compile al ojo... y pueda darme una mano... luego de estoy tengo q iomplementar busqueda con Expresiones regulares, pero eso sera otra historia.

    Gracias.


    Actualizacion

    se arreglo con STRDUP,
    ademas arregle la funcion q libera la memoria // Gracias Sr. ExtañoInocente
    y tambien libero la memoria de las palabras error q detecto Mr. Pangus

    Código:
    //Codigo, codigo codigo...
    void addPalabra(Lista *lista, char *palabra){
        pNodo nuevo, anterior;
     
       nuevo = (pNodo)malloc(sizeof(tipoNodo));
       nuevo->palabra = strdup(palabra);  // duplicar la palabra 
      // mas código... 
    Código:
    /*=======================================================
    UMG 090 04 960 sombradeculto@gmail.com
    Lee Archivo, separa lineas, lee cadenas con STRTOK y almacena en Lista Abierta 
    _________________________________________________________*/
     #include <stdio.h>
    // strcmp
    #include <string.h>
    //free
    #include <malloc.h>
    //PAUSE
    #include <stdlib.h>
       char* token;  //  guarda temporalemte TOKEN obtenido
       char  linea[256]; // Recibe linea a linea del .txt
       char delim[] = {" \n\t"};  // delimitadores para TOKEN
       void serializar (void);  // Proceso que serializa TOKEN y crea lista de palabras
    /*=======================================================
    Estructura para almacenar las palabras para realizar busqueda con expresiones
    _________________________________________________________*/
       typedef struct _nodo{
        char *palabra;
          struct _nodo *siguiente;
       }tipoNodo;
       typedef tipoNodo *Lista;
       typedef tipoNodo *pNodo;
       void addPalabra(Lista *l, char *palabra);
       void freeMem(Lista *);
       void recorrerLista(Lista l);
       int listaVacia(Lista l);
       Lista lista = NULL; // Se crea lista NULL
    //=======================================================
    int main(void){
       freeMem(&lista);
       serializar(); 
       addPalabra(&lista,"HOLA1"); // Envios manuales de cadenas
       addPalabra(&lista,"HOLA2");
       addPalabra(&lista,"HOLA3");
       addPalabra(&lista,NULL);
       addPalabra(&lista,"HOLA5");
       addPalabra(&lista,"HOLA6");
       recorrerLista(lista);
     
       freeMem(&lista);
       recorrerLista(lista);
       system ("PAUSE");
       return 0;
    }
    /*=======================================================
     Abre el archivo lee por lineas separa por palabras y
     envia a estructura de nodos*/
    void serializar (void){
     // Abre el .txt relativo en la carpeta
     FILE *f = fopen("texto.txt","r");
     if (f==NULL){
        perror("Error al abrir el fichero") ;
       }else{
        while ( (fgets(linea,256,f)) != NULL){
             printf("%s\n",linea);
             token = strtok(linea, delim);
             while (token){
                addPalabra(&lista, token);
                token = strtok(NULL, delim);
             };
          };
          fclose(f);
     }
       free(token);
    }
    /*=======================================================
     Inserta Nueva palabra a listado de nodos */
    void addPalabra(Lista *lista, char *palabra){
     pNodo nuevo, anterior;
    
     if ( palabra == NULL || palabra[0] == '0'  || ( strlen(palabra) == 1 && palabra[0] == 'n')  ) return ;
     
     nuevo = (pNodo)malloc(sizeof(tipoNodo));   
     nuevo->palabra = strdup(palabra);
     
     if ( strdup(palabra) == "\0" || strdup(palabra) == "\n" || strdup(palabra) == NULL){ 
      //printf("Llego un null\n");
     }else{
      if (listaVacia(*lista)) {
       nuevo->siguiente = *lista;
       *lista = nuevo;
      }else{
       anterior = *lista;
       while (anterior->siguiente) anterior = anterior->siguiente;
       nuevo->siguiente = anterior->siguiente;
       anterior->siguiente = nuevo;
      }
     }
     free(palabra);
    }
    /*=======================================================
     Revisa si la lista de palabras esta vacia */
    int listaVacia(Lista lista){
     return (lista == NULL);
    }
    /*=======================================================
     Recorre la lista */
    void recorrerLista(Lista lista){
     pNodo nodo = lista;
       if (listaVacia(lista)) printf("Lista Vacia\n");
       else{
          while (nodo){
           printf("LISTA: %s\n", nodo->palabra);
             nodo = nodo->siguiente;
          }
       }
    }
    /*=======================================================
     Libera la memoria utilizada por la lista */
    void freeMem(Lista *lista){
     pNodo nodo;
       while (*lista){
        nodo = *lista;  
          *lista = nodo->siguiente;
          free(nodo->palabra);
          free(nodo);
       }
    }
    
    Editado por Sombradeculto - 29.09.2009 18:10 hs.
    +
     
    0
    Me gusta
     
    http://www.psicofxp.com/forums/programacion.313/961273-lista-abierta-con-tokens-de-strtok.html
    | Más
  • #2 Re: Lista abierta con Tokens de STRTOK

    En addPalabra tenés que copiar las palabras que agregás. Lo que estás haciendo ahora es agregar punteros a partes del vector linea, y cuando reusás el vector para leer la siguiente línea, las palabras que había antes por supuesto se pierden.

    Usá strdup, o malloc+strcpy para copiar las palabras; acordate de liberar la memoria en freeMem.

    Saludos.
    Me gusta este mensaje
  • #3 Re: Lista abierta con Tokens de STRTOK

    SOLUCIONADO
    Muchas gracias por la ayuda... ya actualize mi post para que qde como funciona.

    Originalmente publicado por pangus Ver mensaje
    En addPalabra tenés que copiar las palabras que agregás. Lo que estás haciendo ahora es agregar punteros a partes del vector linea, y cuando reusás el vector para leer la siguiente línea, las palabras que había antes por supuesto se pierden.

    Usá strdup, o malloc+strcpy para copiar las palabras; acordate de liberar la memoria en freeMem.

    Saludos.
    Editado por Sombradeculto - 17.09.2009 13:50 hs.
    Me gusta este mensaje
  • #4 Re: Lista abierta con Tokens de STRTOK

    Te falta al final liberar la memoria reservada por strdup.
    Me gusta este mensaje
  • #5 Re: Lista abierta con Tokens de STRTOK

    Te refieres a...?

    Código:
    free(palabra);
    
    Originalmente publicado por pangus Ver mensaje
    Te falta al final liberar la memoria reservada por strdup.
    Me gusta este mensaje
  • #6 Re: Lista abierta con Tokens de STRTOK

    Originalmente publicado por Sombradeculto Ver mensaje
    Te refieres a...?

    Código:
    free(palabra);
    
    A lo que se refiere pangus, es lo siguiente....

    Vos en tu nodo tenes:

    char* con la palabra almacenada,
    NodoPtr que apunta al siguiente nodo de la lista...

    en tu funcion freeMem(Lista)... lo que haces es

    Obtenes el nodo siguiente, liberas el nodo actual con un free, pero la palabra almacenada dentro del nodo (ese char*) apunta a memoria alocada que no se libera cuando haces free del nodo, ya que el free del nodo libera la memoria a la que apunta el puntero del nodo y no sus atributos internos del struct...

    En freeMem deberias hacer asi:
    while (*lista){
    nodo = *lista;
    *lista = nodo->siguiente;
    free(nodo->palabra); // Esto te faltaba...
    free(nodo);
    }
    Saludos
    Pablo
    Me gusta este mensaje
  • #7 Re: Lista abierta con Tokens de STRTOK

    Listo actualizado el codigo... muchas gracias...

    Originalmente publicado por ExtrañoInocente Ver mensaje
    A lo que se refiere pangus, es lo siguiente....

    Vos en tu nodo tenes:

    char* con la palabra almacenada,
    NodoPtr que apunta al siguiente nodo de la lista...

    en tu funcion freeMem(Lista)... lo que haces es

    Obtenes el nodo siguiente, liberas el nodo actual con un free, pero la palabra almacenada dentro del nodo (ese char*) apunta a memoria alocada que no se libera cuando haces free del nodo, ya que el free del nodo libera la memoria a la que apunta el puntero del nodo y no sus atributos internos del struct...

    En freeMem deberias hacer asi:
    while (*lista){
    nodo = *lista;
    *lista = nodo->siguiente;
    free(nodo->palabra); // Esto te faltaba...
    free(nodo);
    }
    Saludos
    Pablo
    Me gusta este mensaje
  • #8 Re: Lista abierta con Tokens de STRTOK

    Salvo que en addPalabra estás creando un montón de copias que nunca serán reclamadas.
    En lugar de esto
    Código:
     nuevo = (pNodo)malloc(sizeof(tipoNodo));   
     nuevo->palabra = strdup(palabra);
     if ( strdup(palabra) == "\0" || strdup(palabra) == "\n" || strdup(palabra) == NULL){
    
    que crea cuatro copias de palabra; asigna un puntero a la primera copia al campo de la estructura, y compara punteros a las otras tres copias (que después quedan perdidas) con punteros a constantes (nunca va a dar verdadero), hacé esto:
    Código:
     if (palabra == NULL
         || palabra[0] == '\0'
         || strlen(palabra) == 1 && palabra[0] == '\n')
       return;
     nuevo = (pNodo)malloc(sizeof(tipoNodo));   
     nuevo->palabra = strdup(palabra);
    
    Saludos.
    Editado por pangus - 23.09.2009 04:19 hs.
    Me gusta este mensaje
  • #9 Re: Lista abierta con Tokens de STRTOK

    Muchas Gracias por su ayuda...

    En verdad... !!!


    Originalmente publicado por pangus Ver mensaje
    Salvo que en addPalabra estás creando un montón de copias que nunca serán reclamadas.
    En lugar de esto
    Código:
     nuevo = (pNodo)malloc(sizeof(tipoNodo));   
     nuevo->palabra = strdup(palabra);
     if ( strdup(palabra) == "\0" || strdup(palabra) == "\n" || strdup(palabra) == NULL){
    
    que crea cuatro copias de palabra; asigna un puntero a la primera copia al campo de la estructura, y compara punteros a las otras tres copias (que después quedan perdidas) con punteros a constantes (nunca va a dar verdadero), hacé esto:
    Código:
     if (palabra == NULL
         || palabra[0] == '\0'
         || strlen(palabra) == 1 && palabra[0] == '\n')
       return;
     nuevo = (pNodo)malloc(sizeof(tipoNodo));   
     nuevo->palabra = strdup(palabra);
    
    Saludos.
    Me gusta este mensaje
Estás en: Inicio >> Foros >> Informática >> Programación


Estadísticas del tema
  • 8 RESPUESTAS
  • 350 VISTAS
  • 3 USUARIOS RESPONDIERON
 
Ir arriba
Contacto | Acerca de | Ayuda | Términos Legales | privacidad | Pautas de convivencia | Mapa de los foros | TrabajÁ con nosotros
©2008 Psicofxp.com S.A. - Todos los derechos reservados
Certifica IAB