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

 

 


Tema destacado: Usando Git para manipular el directorio de trabajo, el índice y commits (segunda parte)


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


Desconectado Desconectado

Mensajes: 389


Ver Perfil
Lectura y modificacion de archivo
« en: 10 Septiembre 2013, 13:12 pm »

Saludos tengo el siguiente codigo que me lee un archivo de texto y despues lo modifica, en todos los lugares donde se encuentre 1's los intercambia por 5's, la lectura del archivo lo hace bien porque ya verifique y si me ubica los unos del texto el problema es para poder cambiarlos a 5, y no se donde esta el error

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4.  
  5. /*
  6.     Objetivo de la prueba: En una archivo de texto que contiene caracteres alfanuméricos,
  7.     intercambiar el  ‘1’ por el  ‘ 5’ en donde quiera que ocurra esa incidencia en el documento.
  8.     El archivo debe aparecer sin ningún 1, y en su lugar los cincos equivalentes.
  9. */
  10.  
  11. int main()
  12. {
  13.    FILE *fd;
  14.    char letra;
  15.    if((fd = fopen("F:\\archivo_practica11.txt","r+"))!=NULL)
  16.    {
  17.        while(!feof(fd))
  18.        {
  19.            fread(&letra,sizeof(char),1,fd);
  20.            if(letra == '1')
  21.            {
  22.                 letra = '5';
  23.                fwrite(fd,sizeof(char),1,letra);
  24.            }
  25.        }
  26.    }
  27.    else
  28.       printf("No se pudo abrir el archivo");
  29.    return 0;
  30. }
  31.  

gracias


« Última modificación: 10 Septiembre 2013, 13:16 pm por m@o_614 » En línea

eferion


Desconectado Desconectado

Mensajes: 1.248


Ver Perfil
Re: Lectura y modificacion de archivo
« Respuesta #1 en: 10 Septiembre 2013, 13:27 pm »

Cada vez que lees o escribes estás modificando el puntero interno del fichero.

Quiero decir... cuando tu abres un archivo, internamente se crea un puntero de posición. Este puntero es el que indica a partir de donde se van a iniciar las operaciones de lectura / escritura. Cuando tu realizas una de estas operaciones sobre el fichero, dicho puntero se actualiza. Esta es la razón por la que sucesivas escrituras no machacan la misma información sino que se concatenan.

Tu estás leyendo un carácter y, si éste es un '1', escribes un '5' en el fichero. El problema es que al lanzar la operación de lectura el puntero interno ha avanzado una posición y el '5' machaca la posición siguiente.

Para evitar esto tienes que hacer esto:

Código
  1. fread(&letra,sizeof(char),1,fd);
  2.            if(letra == '1')
  3.            {
  4.                fseek( fd, -1, SEEK_CUR );
  5.                 letra = '5';
  6.                fwrite(fd,sizeof(char),1,letra);
  7.            }

De esta forma vuelves a posicionar el puntero sobre el carácter '1' y la operación de escritura machacará dicho carácter.

No he compilado el código, pero debería funcionar.


En línea

rir3760


Desconectado Desconectado

Mensajes: 1.639


Ver Perfil
Re: Lectura y modificacion de archivo
« Respuesta #2 en: 10 Septiembre 2013, 17:45 pm »

Otro error es utilizar la función feof para controlar el bucle (con ello se realiza una iteración de mas) y uno mas es el orden de los argumentos de la función fwrite:
Código
  1. fwrite(fd, sizeof(char), 1, letra);
El primer argumento debe ser la dirección base (de tipo "void *") y el ultimo el archivo a procesar (de tipo "FILE *").

Y no necesitas del encabezado <unistd.h>. Si no tienes una referencia sobre las funciones de la biblioteca estándar de C (C90) deberías conseguir una, mientras eso sucede una aceptable es Standard C.

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
m@o_614


Desconectado Desconectado

Mensajes: 389


Ver Perfil
Re: Lectura y modificacion de archivo
« Respuesta #3 en: 10 Septiembre 2013, 23:30 pm »

Gracias por sus respuestas, le habia hecho al codigo unos cambio de los que me habian dicho, pero ahora sucede que aunque el programa si cambia los 1's por los 5's ahora se cicla infinitamente, y creo que el problema esta en el fseek, porque le puse un contador en el ciclo para que me contara cuantos unos aparecian en el texto y si le ponia fseek no me imprimia nada y si se lo quitaba ya me imprimia correctamente

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4.  
  5. /*
  6.     Objetivo de la prueba: En una archivo de texto que contiene caracteres alfanuméricos,
  7.     intercambiar el  ‘1’ por el  ‘ 5’ en donde quiera que ocurra esa incidencia en el documento.
  8.     El archivo debe aparecer sin ningún 1, y en su lugar los cincos equivalentes.
  9. */
  10.  
  11. int main()
  12. {
  13.   FILE *fd;
  14.   char letra;
  15.   int i = 0;
  16.   if((fd = fopen("F:\\archivo2.txt","r+"))!=NULL)
  17.   {
  18.       while(!feof(fd))
  19.       {
  20.           fread(&letra,sizeof(char),1,fd);
  21.           if(letra == '1')
  22.           {
  23.               fseek(fd,-1,SEEK_CUR);
  24.               letra = '5';
  25.               fwrite(&letra,sizeof(char),1,fd);
  26.               i++;
  27.           }
  28.       }
  29.       printf("%d",i);
  30.   }
  31.   else
  32.      printf("No se pudo abrir el archivo");
  33.   return 0;
  34. }
  35.  
« Última modificación: 10 Septiembre 2013, 23:34 pm por m@o_614 » En línea

eferion


Desconectado Desconectado

Mensajes: 1.248


Ver Perfil
Re: Lectura y modificacion de archivo
« Respuesta #4 en: 10 Septiembre 2013, 23:48 pm »

Ese printf está fuera de los ciclos... salta cuando haya terminado de procesar el archivo...

Código
  1. if((fd = fopen("F:\\archivo2.txt","r+"))!=NULL)
  2.   {
  3.       while(!feof(fd))
  4.       {
  5.           // ...
  6.       }
  7.       printf("%d",i);
  8.   }

y si has abierto el archivo, no te olvides de cerrarlo al final con fclose.
En línea

m@o_614


Desconectado Desconectado

Mensajes: 389


Ver Perfil
Re: Lectura y modificacion de archivo
« Respuesta #5 en: 11 Septiembre 2013, 03:16 am »

En realidad ese printf y el contador ps no sirven para nada, solo queria saber si me estaba contando bien cuantos unos habia, pero ahora ya me di cuenta que el fseek no es el problema!! el problema es cuando le asigno a letra un nuevo valor o en el fwrite, no se bien

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4.  
  5. /*
  6.     Objetivo de la prueba: En una archivo de texto que contiene caracteres alfanuméricos,
  7.     intercambiar el  ‘1’ por el  ‘ 5’ en donde quiera que ocurra esa incidencia en el documento.
  8.     El archivo debe aparecer sin ningún 1, y en su lugar los cincos equivalentes.
  9. */
  10.  
  11. int main()
  12. {
  13.   FILE *fd;
  14.   char letra;
  15.   int n;
  16.   if((fd = fopen("F:\\archivo2.txt","r+"))!=NULL)
  17.   {
  18.          fread(&letra,sizeof(char),1,fd);
  19.           if(letra == '1')
  20.           {
  21.               fseek(fd,-1,SEEK_CUR);
  22.               letra = '5';
  23.               printf("%c",fgetc(fd));
  24.   }
  25.   else
  26.      printf("No se pudo abrir el archivo");
  27.   return 0;
  28. }
  29.  

en el printf que tiene el fgetc  queria ver si la variable letra habia cambiado a 5 pero ya vi que me sigue imprimiendo los unos, me imagino que por ahi esta el problema
« Última modificación: 11 Septiembre 2013, 04:32 am por m@o_614 » En línea

eferion


Desconectado Desconectado

Mensajes: 1.248


Ver Perfil
Re: Lectura y modificacion de archivo
« Respuesta #6 en: 11 Septiembre 2013, 08:17 am »

Código
  1. fread(&letra,sizeof(char),1,fd);
  2.           if(letra == '1')
  3.           {
  4.               fseek(fd,-1,SEEK_CUR);
  5.               letra = '5';
  6.               printf("%c",fgetc(fd));
  7.            }

A ver tu estás haciendo "letra = 5", es decir, estas asignando a una variable de tu programa el valor 5 y, acto seguido, lees del archivo con fgetc... obviamente la asignación no va a afectar al archivo si no le metes un fwrite.

Si quieres hacer esta comprobación tendrás que hacer algo así:

Código
  1. fread(&letra,sizeof(char),1,fd);
  2.           if(letra == '1')
  3.           {
  4.               fseek(fd,-1,SEEK_CUR);
  5.               letra = '5';
  6.               fwrite( &letra, sizeof(char), 1, fd ); // primero modificamos el fichero
  7.               fseek( fd, -1, SEEK_CUR ); // retrocedemos otra vez para poder leer
  8.               printf("%c",fgetc(fd)); // y ahora si leemos lo que deberia ser un 5
  9.            }
En línea

rir3760


Desconectado Desconectado

Mensajes: 1.639


Ver Perfil
Re: Lectura y modificacion de archivo
« Respuesta #7 en: 11 Septiembre 2013, 19:20 pm »

le habia hecho al codigo unos cambio de los que me habian dicho, pero ahora sucede que aunque el programa si cambia los 1's por los 5's ahora se cicla infinitamente
El problema se debe a que en los modos de actualización ("r+", "w+" y "a+") las operaciones de lectura y escritura no pueden realizarse una inmediatamente después de la otra. Siempre después de una operación de lectura se debe indicar la posición en el archivo mediante fseek o rewind si la intención es continuar con una operación de escritura (y al revés): lectura <==> posicionamiento <==> escritura.

En tu caso eso no sucede porque si el carácter '1' se encuentra en el archivo lo sobrescribes con un '5' y a continuación (en la siguiente iteración del bucle) tratas de leer el siguiente carácter, ahí falta la mentada llamada a función.

Para que el programa funcione correctamente se puede utilizar la función ftell para obtener las posiciones antes y después de la lectura del carácter:
Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. int main(void)
  5. {
  6.   FILE *stream;
  7.   long a;
  8.   long b;
  9.   char ch;
  10.  
  11.   if ((stream = fopen("Entrada.txt", "r+")) != NULL){
  12.      while (a = ftell(stream), fread(&ch, 1, 1, stream) == 1){
  13.         if (ch == '1'){
  14.            b = ftell(stream);
  15.  
  16.            fseek(stream, a, SEEK_SET);
  17.            ch = '5';
  18.            fwrite(&ch, 1, 1, stream);
  19.            fseek(stream, b, SEEK_SET);
  20.         }
  21.      }
  22.  
  23.      fclose(stream);
  24.   }
  25.  
  26.   return 0;
  27. }

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
m@o_614


Desconectado Desconectado

Mensajes: 389


Ver Perfil
Re: Lectura y modificacion de archivo
« Respuesta #8 en: 12 Septiembre 2013, 01:58 am »

muchas gracias rir3760 nunca se me hubiera ocurrido que cuando haces una actualizacion no se puede leer y despues escribir luego. Una ultima pregunta, por que antes del fread siempre se tiene que utilizar el ftell???
En línea

rir3760


Desconectado Desconectado

Mensajes: 1.639


Ver Perfil
Re: Lectura y modificacion de archivo
« Respuesta #9 en: 12 Septiembre 2013, 15:40 pm »

por que antes del fread siempre se tiene que utilizar el ftell?
Porque no sabemos de antemano si el carácter que vamos a leer cumplirá o no con la condición, si es igual a '1' debemos regresar a la posición anterior (ftell + fseek) y sobrescribir ese carácter (fwrite).

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:  

WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines