elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Arreglado, de nuevo, el registro del warzone (wargame) de EHN


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  problema con archivos
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: problema con archivos  (Leído 3,987 veces)
m@o_614


Desconectado Desconectado

Mensajes: 389


Ver Perfil
problema con archivos
« en: 1 Octubre 2013, 20:22 pm »

Saludos tengo el siguiente programa que me lee un archivo que tiene nombres de personas separados por una coma y me pide que le ingrese un nombre y al final me tiene que imprimir el numero de veces que aparece ese nombre en el archivo solo que no me imprime la cantidad correcta

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #define TAM 10
  5.  
  6. int main()
  7. {
  8.    FILE *fd;
  9.    int i = 0,j = 0,tam;
  10.    char captura[TAM],*cadena,*nombre,car;
  11.    if((fd = fopen("F:\\nombre_archivo.txt","r"))!= NULL)
  12.    {
  13.        printf("Capture nombre a buscar: ");
  14.        fgets(captura,TAM,stdin);
  15.        tam = strlen(captura);
  16.        nombre = (char*)malloc((tam+1)*sizeof(char));
  17.        cadena = (char*)malloc((tam+1)*sizeof(char));
  18.        strcpy(nombre,captura);
  19.        while((car  = fgetc(fd))!=EOF)
  20.        {
  21.            while((car = fgetc(fd))!= ',')
  22.            {
  23.                cadena[j] = car;
  24.                j++;
  25.            }
  26.            j = 0;
  27.            if((strcmp(cadena,nombre)) == 0)
  28.               i++;
  29.        }
  30.        printf("El nombre %s se encuentra %d veces en el archivo\n",nombre,i);
  31.    }
  32.    else
  33.       printf("No se pudo abrir archivo");
  34.    return 0;
  35. }
  36.  

gracias de antemano


« Última modificación: 1 Octubre 2013, 21:58 pm por m@o_614 » En línea

eferion


Desconectado Desconectado

Mensajes: 1.248


Ver Perfil
Re: problema con archivos
« Respuesta #1 en: 2 Octubre 2013, 08:32 am »

Código
  1. while((car = fgetc(fd))!= ',')
  2.            {
  3.                cadena[j] = car;
  4.                j++;
  5.            }
  6.            j = 0;
  7.            if((strcmp(cadena,nombre)) == 0)
  8.               i++;

Como bien sabrás, las cadenas tienen que terminar en '\0'... ahí no estás poniendo dicho caracter, luego a saber qué es lo que estás comparando.

Un ejemplo:

nombres: pablo,antonio,pablo
nombre buscado: pablo

primer nombre:
* cadena = pabloS$FG´}S¿S-er
* encuentra el nombre: no
* motivo: cadena no está inicializada y tiene basura

Al encontrar una coma sería altamente recomendable introducir un nulo en la cadena para tener un nombre con sentido.

Además es posible que el último nombre no termine en coma, luego el algoritmo te puede fallar si el último nombre del archivo es el buscado.

Adicionalmente, el bucle para localizar las comas lo puedes eliminar si haces uso de la función strtok.

Un saludo.


En línea

m@o_614


Desconectado Desconectado

Mensajes: 389


Ver Perfil
Re: problema con archivos
« Respuesta #2 en: 2 Octubre 2013, 17:45 pm »

Saludos eferion gracias por tu respuesta, a que te refieres con que la cadena no esta inicializada?? yo tenia entendido que en el momento de recorrer el archivo y asignarle a cadena[j] = car; caracter por caracter eso ya era inicializarla
En línea

eferion


Desconectado Desconectado

Mensajes: 1.248


Ver Perfil
Re: problema con archivos
« Respuesta #3 en: 2 Octubre 2013, 20:04 pm »

Código
  1. char cadena[10];
  2. cadena[ 0 ] = 'A';
  3. printf( "%s", cadena );

Puedes ejecutar este código unas 200 veces que las 200 va a fallar el programa, bien con una violación de segmento, bien mostrando un montón de ***** en pantalla.

Cuando el programa reserva memoria ( de forma automática o tú con malloc ), ésta no se inicializa de forma automática... tiene basura, que no es otra cosa que información aleatoria ( si esa memoria no ha sido utilizada desde que se arrancó el equipo ) u obsoleta ( si esa memoria ha sido utilizada por otro programa que la ha modificado para sus usos y después la ha liberado ). En cualquier caso no es información útil para ti.

Si en el ejemplo de arriba tu quieres que el printf saque por pantalla símplemente la A tienes que asegurarte de finalizar la cadena. En c las cadenas de texto se finalizan con un caracter nulo, luego la forma correcta de actuar sería:

Código
  1. char cadena[10];
  2. cadena[ 0 ] = 'A';
  3. cadena[ 1 ] = '\0';
  4. printf( "%s", cadena );

Ahora, el 100% de las ejecuciones van a sacar una única A por pantalla.
En línea

m@o_614


Desconectado Desconectado

Mensajes: 389


Ver Perfil
Re: problema con archivos
« Respuesta #4 en: 2 Octubre 2013, 20:57 pm »

si ya entendi que cada vez que me encuentre una coma tengo que agregarle el final de linea, y tambien le cambie otras cosas al codigo como que tambien le quite el salto de linea en el fgets y cada vez que compare el nombre con el otro nombre que tengo almacenado en cadena limpio el arreglo con memset(), para que cada vez despues de la coma ingrese un nuevo nombre a un buffer limpio pero aun asi no funciona

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #define TAM 10
  5.  
  6. int main()
  7. {
  8.    FILE *fd;
  9.    int i,j,tam;
  10.    char nombre[TAM],*cadena,car,*ptr;
  11.    if((fd = fopen("F:\\nombre_archivo.txt","r"))!= NULL)
  12.    {
  13.        printf("Capture nombre a buscar: ");
  14.        fgets(nombre,TAM,stdin);
  15.        if((ptr = strchr(nombre,'\n')) != NULL)
  16.           *ptr = '\0';
  17.        tam = strlen(nombre);
  18.        cadena  = (char*)malloc((tam+1)*sizeof(char));
  19.        i = 0;
  20.        while(!feof(fd))
  21.        {
  22.            j = 0;
  23.            while((car = fgetc(fd))!= ',')
  24.            {
  25.                cadena[j] = car;
  26.                j++;
  27.            }
  28.            cadena[j] = '\0';
  29.            if((strcmp(cadena,nombre)) == 0)
  30.               i++;
  31.            memset(cadena,0,tam+1);
  32.        }
  33.        printf("El nombre %s se encuentra %d veces en el archivo\n",nombre,i);
  34.    }
  35.    else
  36.       printf("No se pudo abrir archivo");
  37.    return 0;
  38. }

gracias
En línea

eferion


Desconectado Desconectado

Mensajes: 1.248


Ver Perfil
Re: problema con archivos
« Respuesta #5 en: 2 Octubre 2013, 21:13 pm »

Tienes varios fallos:

* Cadena no puede tener la longitud del nombre buscado más uno. Te pongo un ejemplo, si buscas ANGEL y el nombre que te toca leer es ROBERTO... pues ROBERTO no va a entrar en 6 caracteres, necesita 8. Lo ideal es que cadena tenga una longitud lo suficentemente larga como para aceptar cualquier nombre. 100 o 200 caracteres suelen ser suficientes.

* El memset no te sirve para nada, ya terminas la cadena con el '\0', luego cadena siempre va a contener un string válido.

* La variable tam puedes eliminarla sin problemas, no la necesitas para nada.

* TAM está definida a 10, esto te limita el nombre a buscar a 9 caracteres... igual que con el primer punto, te puedes permitir el lujo de ampliarlo un poco.

* La línea del strchr no tiene mucha lógica... cuando tu lees con fgets ya te está finalizando la cadena con '\0'

Y así a bote pronto no veo nada más. Corrige eso a ver si te funciona mejor.

Un saludo.
En línea

ecfisa

Desconectado Desconectado

Mensajes: 114


Ver Perfil
Re: problema con archivos
« Respuesta #6 en: 2 Octubre 2013, 21:41 pm »

Hola.

Otro problema que veo, es que estas presuponiendo que "cadena" va a tener el mismo largo que "nombre" ya que con malloc le reservas la misma cantidad de memoria.

Me explico, si por ejemplo ingresas "Ana" y en el archivo existe el nombre "Hermenegildo" cuando leas ese nombre, la variable "cadena" no va a tener el  espacio necesario para almacenarlo...

Proba de este modo:
Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #define TAM 50
  5.  
  6. int main()
  7. {
  8.    FILE *fd;
  9.    int veces = 0, i;
  10.    char captura[TAM], *cadena, *nombre, car;
  11.  
  12.    if((fd = fopen("F:\\nombre_archivo.txt", "r"))== NULL) {
  13.      printf("Error abriendo archivo");
  14.      return EXIT_FAILURE;
  15.    }
  16.  
  17.    printf("Ingrese nombre a buscar: ");
  18.    fgets(captura, TAM, stdin);
  19.    captura[strlen(captura)-1] = '\0';
  20.  
  21.    nombre = (char*)malloc(strlen(captura)*sizeof(char));
  22.    cadena = (char*)malloc(sizeof(char));
  23.    strcpy(nombre, captura);
  24.  
  25.    while(!feof(fd)) {
  26.      i = 0;
  27.      while(!feof(fd) && (car = fgetc(fd)) != ','  ) {
  28.        cadena = (char*)realloc(cadena,(i+1)*sizeof(char));
  29.        cadena[i++] = car;
  30.      }
  31.      cadena[i] = '\0';
  32.      if(strcmp(cadena, nombre) == 0) veces++;
  33.    }
  34.  
  35.    printf("El nombre %s ");
  36.    switch(veces) {
  37.      case 0: printf("no se encuentra en el archivo.\n");break;
  38.      case 1: printf("se encuentra 1 vez en el archivo.\n");break;
  39.      default:
  40.        printf("se encuentra %d veces en el archivo.\n",veces);
  41.    }
  42.  
  43.    free(cadena);
  44.    free(nombre);
  45.  
  46.    return EXIT_SUCCESS;
  47. }
  48.  

El ejemplo no contempla que el archivo finalize sin una coma. Si no la tiene y buscas un nombre que esté al final, contabilizará una ocurrencia menos o no lo encontrará de ser el único.

Saludos :)

Edito: Veo que mientras escribía eferion ya señalizó esta falla.
« Última modificación: 2 Octubre 2013, 21:44 pm por ecfisa » En línea

m@o_614


Desconectado Desconectado

Mensajes: 389


Ver Perfil
Re: problema con archivos
« Respuesta #7 en: 2 Octubre 2013, 23:55 pm »

Ahora el programa ya me hace lo que le pido, solo que tengo que corregir esa ultima falla de si el nombre buscado se encuentra al final que tambien lo contabilice, ecfisa una ultima duda, por que en tu programa pusiste la funcion feof() en dos whiles?? no es suficiente con uno??

Código
  1.  while(!feof(fd)) {
  2.      i = 0;
  3.      while(!feof(fd) && (car = fgetc(fd)) != ','  ) {
  4.        cadena = (char*)realloc(cadena,(i+1)*sizeof(char));
  5.        cadena[i++] = car;
  6.      }
  7.      cadena[i] = '\0';
  8.      if(strcmp(cadena, nombre) == 0) veces++;
  9.    }


por que cambie el codigo un poco y con este detalle me funciona pero si le quito un feof ya no funciona, le tengo que poner 2:

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #define TAM 20
  5.  
  6. int main()
  7. {
  8.    FILE *fd;
  9.    int i = 0,j;
  10.    char nombre[TAM],cadena[TAM],car,*ptr;
  11.    if((fd = fopen("F:\\nombre_archivo.txt","r"))!= NULL)
  12.    {
  13.        printf("Capture nombre a buscar: ");
  14.        fgets(nombre,TAM,stdin);
  15.        if((ptr = strchr(nombre,'\n')) != NULL)
  16.           *ptr = '\0';
  17.        while(!feof(fd))
  18.        {
  19.            j = 0;
  20.            while((car = fgetc(fd))!= ','&& !feof(fd))
  21.                cadena[j++] = car;
  22.            cadena[j] = '\0';
  23.            if((strcmp(cadena,nombre)) == 0)
  24.               i++;
  25.        }
  26.        printf("El nombre %s aparece %d veces en el archivo\n",nombre,i);
  27.    }
  28.    else
  29.       printf("No se pudo abrir archivo");
  30.    return 0;
  31. }
  32.  

muchas gracias a ambos por sus respuestas

saludos
En línea

ecfisa

Desconectado Desconectado

Mensajes: 114


Ver Perfil
Re: problema con archivos
« Respuesta #8 en: 3 Octubre 2013, 07:11 am »

ecfisa una ultima duda, por que en tu programa pusiste la funcion feof() en dos whiles?? 
Hola.

Por que de ese modo el ciclo interior puede detectar el fin del archivo, saber que no existen mas caracteres para leer y por tanto finalizar.

Tal vez te resulte mas claro si se expande un poco el código:
Código
  1. ...
  2.   // mientras no fin de archivo
  3.   while(!feof(fd)) {  
  4.      i = 0;
  5.      // leer 1 caracter
  6.      car = fgetc(fd);
  7.     // mientras no fin de archivo y el caracter es distinto de ','
  8.      while(!feof(fd) && car != ',')
  9.        // almacenar en variable "cadena"
  10.        cadena = (char*)realloc(cadena,(i+1)*sizeof(char));
  11.        cadena[i++] = car;  
  12.        // leer proximo caracter
  13.        car = fgetc(fd);              
  14.      } // ( se lleyo fin de archivo o una coma )
  15.      cadena[i] = '\0';
  16.      if(strcmp(cadena, nombre) == 0) veces++;
  17.    } //( si "car" es coma continua, si es EOF finaliza )
  18. ...
  19.  

Saludos :)
En línea

rir3760


Desconectado Desconectado

Mensajes: 1.639


Ver Perfil
Re: problema con archivos
« Respuesta #9 en: 3 Octubre 2013, 18:52 pm »

Ahora el programa ya me hace lo que le pido, solo que tengo que corregir esa ultima falla de si el nombre buscado se encuentra al final que tambien lo contabilice
Ademas de las recomendaciones que ya te dieron hay que cambiar el tipo de la variable "car" ya que el valor de retorno de fgetc es int, hay que cerrar el archivo con fclose y se puede eliminar el uso de feof si, en su lugar, se verifica el valor de retorno de fgetc:
Código
  1. j = 0;
  2. do {
  3.   if ((car = fgetc(fd)) == ',' || car == EOF){
  4.      cadena[j] = '\0';
  5.      if ((strcmp(cadena, nombre)) == 0)
  6.         i++;
  7.      j = 0;
  8.   }else
  9.      cadena[j++] = car;
  10. }while (car != EOF);
  11. fclose(fd);

Algo que no mencionas es si el archivo consiste de una sola linea o varias, en el segundo caso se debe considerar al avance de linea como otro separador. Una opciona aqui es utilizar la funcion fscanf para obtener cada uno de los nombres:
Código
  1. while (fscanf(fd, "%[^,\n]%*c", cadena) == 1)
  2.   if ((strcmp(cadena, nombre)) == 0)
  3.      i++;
  4. fclose(fd);

Un saludo
En línea

C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Problema con archivos
Multimedia
_Joselo_ 3 1,842 Último mensaje 14 Enero 2005, 21:04 pm
por ....Gusto....
Problema con archivos de un cd
Software
ienova 0 2,331 Último mensaje 11 Mayo 2006, 21:42 pm
por ienova
Problema con archivos
Java
Ruusa 2 2,669 Último mensaje 23 Octubre 2020, 11:16 am
por rub'n
Problema con archivos pcx.
Software
Tachikomaia 5 1,371 Último mensaje 12 Marzo 2024, 17:40 pm
por EdePC
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines