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

[SOLUCIONADO] Extraer palabras de un fichero de texto

Estas en el tema de Extraer palabras de un fichero de texto en el foro de C/C++ en Foros del Web. Hola: Tengo una duda y además estoy totalmente perdido y no adivino el por qué no funciona: Se trata de leer un archivo de texto. ...
  #1 (permalink)  
Antiguo 13/12/2013, 17:46
 
Fecha de Ingreso: septiembre-2010
Mensajes: 494
Antigüedad: 13 años, 7 meses
Puntos: 10
Extraer palabras de un fichero de texto

Hola:

Tengo una duda y además estoy totalmente perdido y no adivino el por qué no funciona:

Se trata de leer un archivo de texto. Me interesa que se lea línea a línea, y además, luego, de cada línea quiero sacar todas las palabras. Ha de ser de esa forma.
Esto es lo que tengo:
Código C++:
Ver original
  1. #include <iostream>
  2. #include <fstream>
  3. #include <cstring>
  4.  
  5. using namespace std;
  6.  
  7. void divideLinea(char*);
  8.  
  9. int main()
  10. {
  11.     char buffer[2000];
  12.     ifstream archivo("texto.txt");
  13.  
  14.     while (!archivo.eof())
  15.     {
  16.         archivo.getline(buffer,2000);
  17.         cout<<endl<<buffer;
  18.         //divideLinea (buffer);
  19.     }
  20.     archivo.close();
  21.     return 0;
  22. }
  23.  
  24. void divideLinea(char* buffer)
  25. {
  26.     char *p;
  27.     p= strtok (buffer," ");
  28.     cout<<p<<endl;
  29.     while (p)
  30.     {
  31.         p=strtok (0," ");
  32.         cout<<p<<endl;
  33.     }
  34. }

Si descomento la llamada a la función, después de la primera iteración del bucle ya no vuelve a funcionar, y es ahí donde estoy totalmente perdido.

Gracias!
  #2 (permalink)  
Antiguo 14/12/2013, 07:54
 
Fecha de Ingreso: agosto-2012
Mensajes: 601
Antigüedad: 11 años, 8 meses
Puntos: 83
Respuesta: Extraer palabas de un fichero de texto

Una cosa:

Código C++:
Ver original
  1. while(p) {
  2.         p = strtok(0, " ");//cuando strtok sea nulo
  3.         cout << p << endl;//que pasará con esta linea?
  4. }

Código C++:
Ver original
  1. while(p) {
  2.         cout << p << endl;//solo he cambiado el orden
  3.         p = strtok(0, " ");
  4.         cout << p << endl;
  5. }

Echa un vistazo a este hilo http://www.forosdelweb.com/f96/conta...adena-1082761/, puede que te sea de ayuda.

Saludos
vosk
  #3 (permalink)  
Antiguo 18/12/2013, 04:42
 
Fecha de Ingreso: septiembre-2010
Mensajes: 494
Antigüedad: 13 años, 7 meses
Puntos: 10
Respuesta: Extraer palabas de un fichero de texto

Hola vosk:

Muchas gracias por la aclaración. Tienes toda la razón.
Si no te he respondido antes es porque me sigo peleando con lo que quiero hacer y con strtok. Incluso en estos días he tenido la osadía de responder a algunas dudas con cierta relación con lo mío

El caso es que no debo de entender bien el funcionamiento de strtok. Lo he mirado aqui:
http://support.microsoft.com/kb/51327/es

Exceptuando que en la versión Microsoft parece que se aceptan dos delimitadores, entiendo que la función se comporta igual.

Sin embargo, cuando tengo dos caracteres a cambiar seguidos,me deja uno de ellos.
Pongo un ejemplo:
Código C++:
Ver original
  1. #include <iostream>
  2. #include <cstring>
  3.  
  4. using namespace std;
  5.  
  6. int main()
  7. {
  8.     char frase[]={"La primera linea\n\nLa segunda linea\n\nLa tercera linea."};
  9.     char *p;
  10.     int i=0;
  11.     p=strtok (frase,"\n");
  12.     while (p!=0)
  13.     {
  14.        p=strtok(0,"\n");
  15.     }
  16.     while (frase[i]!='.')
  17.     {
  18.         if (frase[i]=='\n')
  19.         cout<<'$';
  20.         else
  21.         cout<<frase[i];
  22.         i++;
  23.     }
  24.     return 0;
  25. }

El primer "\n" lo reemplaza por "\0", como era de esperar, pero el segundo lo deja.
¿Puede ser que no tenga bien planteada la forma de uso?
Gracias!
  #4 (permalink)  
Antiguo 18/12/2013, 11:29
 
Fecha de Ingreso: agosto-2012
Mensajes: 601
Antigüedad: 11 años, 8 meses
Puntos: 83
Respuesta: Extraer palabas de un fichero de texto

Es lo que te dije al final del post: mira este otro hilo http://www.forosdelweb.com/f96/conta...adena-1082761/, en ese hilo se plantea como contar palabras aun cuando haya mas de un espacio o cualquier otro signo de puntuacion, tu caso es el mismo pero en vez de signos de puntuacion estas buscando saltos de linea.

Saludos
vosk
  #5 (permalink)  
Antiguo 18/12/2013, 12:44
 
Fecha de Ingreso: septiembre-2010
Mensajes: 494
Antigüedad: 13 años, 7 meses
Puntos: 10
Respuesta: Extraer palabas de un fichero de texto

Hola vosk:

Es que creo que busco algo diferente, aunque después de tantas horas no sé si ya estoy perdiendo la perspectiva.

Supongamos que tengo el siguiente archivo de texto. Lo he pasado a un char:
Código C++:
Ver original
  1. char datos[]="\n\n$registro1#dato11#dato12#dato13$registro2#dato21#dato22largooooooooooo\nooooooooo#dato23\n$registro3#dato13##dato33";

Bueno, pertenece a una base de datos cuyos registros empiezan por $, y dentro de ellos cada campo está separado por #.
Por otro lado algun campo puede ser muy grande y tener dentro párrafos separados con \n que interesa mantener.
También pueden existir campos nulos que han de estar reflejados.
Por último, aunque es recomendable, no siempre los registros estarán separados por un \n (realmente no se da el caso, pero podría darse, así que mejor no dejar esa debilidad). Eso quiere decir que la separacion entre registros no es un salto de línea, sino el símbolo $.
Y además puede haber saltos de línea al principio.

Con todas estas cosas, me gustaría hacer que el programa cogiera un registro, lo dividiera en campos, y luego el segundo, lo dividiera en campos y así.
Pero no que divida todos los campos de una vez.
Así, en el ejemplo habría de hacer:

Extraigo el primer registro:
registro1#dato11#dato12#dato13

Separo los campos y los muestro:
Campo1: dato11
Campo2: dato12
Campo3: dato13

Extraigo el segundo registro:
registro2#dato21#dato22largooooooooooo\nooooooooo# dato23#dato24

Separo los campos y los muestro:
Campo 1: dato21
Campo2: dato22largooooooooooo\nooooooooo //(me interesa mantener ese \n)
Campo3: dato23

Extraigo el tercer registro:
registro3#dato13##dato33

Separo los campos y los muestro:
Campo1: dato13
Campo2: (vacio) interesa que exista aunque esté vacio
Campo3: dato 33

Uff...pues mira que no me parecía complicado, pero no consigo que me salga.
De todas formas me miro de nuevo el post que me has dicho, entre otras cosas ya me queda confirmado que se pueden usar varios delimitadores diferentes y además (momento peloteo) me ha gustado el código que has puesto, aunque he de terminar de interiorizarlo.
Saludos
  #6 (permalink)  
Antiguo 18/12/2013, 13:19
 
Fecha de Ingreso: septiembre-2010
Mensajes: 494
Antigüedad: 13 años, 7 meses
Puntos: 10
Respuesta: Extraer palabas de un fichero de texto

Vuelvo a dar otra vuelta sobre la misma idea, pero obtengo el mismo fallo:
Código C++:
Ver original
  1. #include <iostream>
  2. #include <cstring>
  3.  
  4. using namespace std;
  5. void divideLinea(char*);
  6.  
  7. int main()
  8. {
  9.     char datos[]="\n\n$registro1#dato11#dato12#dato13$registro2#dato21#dato22largooooooooooo\nooooooooo#dato23#dato24\n$registro3#dato13##dato33";
  10.     int tam=strlen(datos);
  11.     //metodo cutre para quitar saltos de linea al principio y entre registros
  12.     for (int i=0;i<tam;i++)
  13.     {
  14.         if (datos[i]=='\n' && (datos[i+1]=='\n' || datos[i+1]=='$'))
  15.         datos[i]='$';
  16.     }
  17.     //fin del metodo cutre
  18.     char *p;
  19.     char token[]="$";
  20.  
  21.     p=strtok (datos,token);
  22.     while (p)
  23.     {
  24.         divideLinea(p);//sustituir por cout<<p<<endl; y funcionará bien
  25.         p=strtok(0,token);
  26.     }
  27.     return 0;
  28. }
  29.  
  30. void divideLinea(char* linea)
  31. {
  32.     char* p;
  33.     char token[]="#";
  34.     char buffer[300];
  35.     strcpy (buffer,linea);
  36.     cout<<"linea: "<<buffer<<endl;
  37.     p=strtok (buffer,token);
  38.     while (p)
  39.     {
  40.         p=strtok (0,token);
  41.         cout<<p<<endl;
  42.     }
  43. }

Sigo sin saber por qué la funcion divideLinea modifica el funcionamiento del bucle que se encuentra en la función principal
  #7 (permalink)  
Antiguo 18/12/2013, 17:08
 
Fecha de Ingreso: septiembre-2010
Mensajes: 494
Antigüedad: 13 años, 7 meses
Puntos: 10
Respuesta: Extraer palabras de un fichero de texto

Al final no he usado strtok en la función...y arreglado
Código C++:
Ver original
  1. #include <iostream>
  2. #include <cstring>
  3.  
  4. using namespace std;
  5. void divideLinea(char*);
  6.  
  7. int main()
  8. {
  9.     char datos[]="\n\n$registro1#dato11#dato12#dato13$registro2#dato21#dato22largooooooooooo\nooooooooo#dato23#dato24\n$registro3#dato13##dato33";
  10.     int tam=strlen(datos);
  11.     //metodo cutre para quitar saltos de linea al principio y entre registros
  12.     for (int i=0; i<tam; i++)
  13.     {
  14.         if (datos[i]=='\n' && (datos[i+1]=='\n' || datos[i+1]=='$'))
  15.             datos[i]='$';
  16.     }
  17.     //fin del metodo cutre
  18.     char *p;
  19.     char token[]="$";
  20.  
  21.     p=strtok (datos,token);
  22.     while (p)
  23.     {
  24.         divideLinea(p);
  25.         p=strtok(0,token);
  26.     }
  27.     return 0;
  28. }
  29.  
  30. void divideLinea(char* linea)
  31. {
  32.     int i=0;
  33.     char *punt=linea;
  34.     cout<<"Linea a procesar: "<<linea<<endl;
  35.     while (linea[i]!='\0')
  36.     {
  37.         if (linea[i]=='#')
  38.         {
  39.             linea[i]='\0';
  40.             cout<<"dato: "<<punt<<endl;
  41.             punt=&linea[i+1];
  42.         }
  43.         i++;
  44.     }
  45.     cout<<"dato: "<<punt<<endl;
  46. }

Etiquetas: fichero, funcion, int, string
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 13:31.