Foros del Web » Programación para mayores de 30 ;) » Programación General »

[Lenguaje C] Fallo en programa que hace copias de ficheros

Estas en el tema de [Lenguaje C] Fallo en programa que hace copias de ficheros en el foro de Programación General en Foros del Web. Llevo todo el día pegandome con un error y no le encuentro explicación. Para mostraros el problema me he hecho un programa de prueba que ...
  #1 (permalink)  
Antiguo 05/12/2004, 10:36
Avatar de ferny
Il capo della mafia
 
Fecha de Ingreso: febrero-2002
Ubicación: Al final del cable
Mensajes: 10.080
Antigüedad: 22 años, 2 meses
Puntos: 55
[Lenguaje C] Fallo en programa que hace copias de ficheros

Llevo todo el día pegandome con un error y no le encuentro explicación. Para mostraros el problema me he hecho un programa de prueba que simplemente hace una copia de un fichero. Acá va:


Código PHP:
#include <stdio.h>

int main(void) {
        
FILE *f1,*f2;
        
unsigned long inputsize,i;
        
unsigned char c;
        
        
f1 fopen("Prueba.txt","r");
        
f2 fopen("Prueba.copia.txt","w");

        
/* Tamaño del fichero (esta parte está comprobado que funciona) */
        
fseek(f1,0,SEEK_END);
        
inputsize ftell(f1);
        
fseek(f1,0,SEEK_SET); 
             
        for (
i=0;i<inputsize;i++) {
            
fscanf(f1,"%c",&c);
            
fprintf(f2,"%c",c);
        }

        
printf("Copia realizada\n");
        
system("pause");

        
fclose(f1);
        
fclose(f2);
        return 
0;

El caso es que la copia la hace bien, pero al final del archivo añade caracteres que coinciden con el último caracter del fichero, y me he fijado que añade tantos como lineas tenga el fichero menos una.

Por ejemplo, si el fichero original es éste:


Código:
Linea 1
Linea 2
Linea 3
Linea 4
El fichero "copia" es este otro:


Código:
Linea 1
Linea 2
Linea 3
Linea 4444
Pero lo más desconcertante es que me pasa sólo en Windows, si el mismo programa lo compilo y pruebo en Linux, funciona perfectamente.

En linux estoy usando el compilador GCC y en Windows uso DevC++ que creo que también trae el compilador GCC.

¿Es por algún error en la programación, o es por la mie*** del Windows?
__________________
www.mundodivx.com || www.mundodivx.org

Pon tu mano en un horno caliente durante un minuto y te parecerá una hora.
Siéntate junto a una chica preciosa durante una hora y te parecerá un minuto.
Eso es la relatividad.
  #2 (permalink)  
Antiguo 05/12/2004, 11:04
Avatar de Eternal Idol  
Fecha de Ingreso: mayo-2004
Ubicación: Lucentum
Mensajes: 6.192
Antigüedad: 19 años, 11 meses
Puntos: 74
Primero que nada me parece que el método que utilizas para copiar los archivos deja bastante que desear y que Windows (NT>4) es un Sistema Operativo muy fiable.

Cambiá esto y funcionará:

Código:
f1 = fopen("Prueba.txt","rb"); 
f2 = fopen("Prueba.copia.txt","wb");
__________________
¡Peron cumple, Evita dignifica! VIVA PERON CARAJO

Última edición por Eternal Idol; 05/12/2004 a las 11:16
  #3 (permalink)  
Antiguo 05/12/2004, 11:15
Avatar de ferny
Il capo della mafia
 
Fecha de Ingreso: febrero-2002
Ubicación: Al final del cable
Mensajes: 10.080
Antigüedad: 22 años, 2 meses
Puntos: 55
¿Te creerás que ha funcionado perfectamente? ¡GRACIAS!

No es que use ese método para copiar archivos, es sólo un programita que hice para mostrar el error que me ocurría. Realmente lo que estoy desarrollando es un sistema de encriptación de archivos utilizando AES, y el error venía al guardar los archivos pero no sabía el motivo... por eso hice este programa de prueba para escribir mi post.

¿Sería mucho pedir que me explicaras el motivo de que así funcione? Es que me resulta demasiado curioso...

Gracias de nuevo
__________________
www.mundodivx.com || www.mundodivx.org

Pon tu mano en un horno caliente durante un minuto y te parecerá una hora.
Siéntate junto a una chica preciosa durante una hora y te parecerá un minuto.
Eso es la relatividad.
  #4 (permalink)  
Antiguo 05/12/2004, 11:17
Avatar de Eternal Idol  
Fecha de Ingreso: mayo-2004
Ubicación: Lucentum
Mensajes: 6.192
Antigüedad: 19 años, 11 meses
Puntos: 74
Por supuesto que funciona, antes de responderte lo probé.

El problema es una pequeña diferencia en el tratamiento de los saltos de linea en archivos de texto. Según tengo entendido Linux utiliza solo el caracter \n (0x0A) mientras que Windows utiliza \r\n (0x0D) si usaras un archivo con saltos de lineas tipo Linux también te funcionaría en Windows.

La "solución" es no leer el archivo como texto sino como binario, esto es solo un tecnicismo ya que los archivos solo pueden contener bytes pero el compilador los trata de diferente manera según este en modo texto o binario.

Realmente no importa lo que estes haciendo si no usas buffers es un método deficiente y muy poco optimizado. Las operaciones de entrada y salida de archivos son muy lentas.
__________________
¡Peron cumple, Evita dignifica! VIVA PERON CARAJO

Última edición por Eternal Idol; 05/12/2004 a las 11:18
  #5 (permalink)  
Antiguo 05/12/2004, 15:03
Avatar de ferny
Il capo della mafia
 
Fecha de Ingreso: febrero-2002
Ubicación: Al final del cable
Mensajes: 10.080
Antigüedad: 22 años, 2 meses
Puntos: 55
En mi aplicación real sí estoy usando buffers, supongo que eso será lo correcto ¿no? O sea, primero leo el fichero de entrada y lo guardo en un buffer de entrada, lo opero y el resultado lo almaceno en un buffer de salida, y al final este buffer de salida lo copio al nuevo fichero. Teniendo en cuenta que son muchas las operaciones a realizar, y que se hace por definición en grupos de 16 bytes, tarda relativamente poco, un archivo de 50 MB me lo encripta en menos de 3 minutos

Yo me imaginaba que el error tenía algo que ver por los caracteres de salto de linea que comentabas (curioso que el nº de repeticiones del final era igual al nº de lineas y además funcionaba en Linux) pero ni de pasada se me abría ocurrido que era por el rb y el wb Una cosa que ya sé

Tendré que cambiar mi manual de C, en el que tengo me dice que abra los archivos con r y w y no comenta más al respecto...

Pues muchas gracias, con tu ayuda ya he podido terminar la aplicación
__________________
www.mundodivx.com || www.mundodivx.org

Pon tu mano en un horno caliente durante un minuto y te parecerá una hora.
Siéntate junto a una chica preciosa durante una hora y te parecerá un minuto.
Eso es la relatividad.
  #6 (permalink)  
Antiguo 05/12/2004, 16:23
Avatar de Eternal Idol  
Fecha de Ingreso: mayo-2004
Ubicación: Lucentum
Mensajes: 6.192
Antigüedad: 19 años, 11 meses
Puntos: 74
De nada, yo saqué la información directamente de la MSDN (gracias Microsoft por tener la mejor documentación) ya que generalmente no uso funciones de C.
__________________
¡Peron cumple, Evita dignifica! VIVA PERON CARAJO
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 16:57.