¿Por qué no funciona correctamente este programa? Ficheros inside

Iniciado por NathanD, 25 Febrero 2013, 18:38 PM

0 Miembros y 2 Visitantes están viendo este tema.

NathanD

Tengo que hacer un programa que coja un fichero de texto y lo divida en otros varios archivos, de extensión .001, .002, etc. En cuántas partes quiere dividirlo, lo introduce el usuario. Mi programa funciona a veces sí, a veces no...

Os dejo el bucle principal del código:



cantidad_por_fich = fread( buffer, 1, sizeof(buffer), fichero_orig);
cantidad_por_fich /= num_partes;

for(i=0; i < num_partes; i++)
{
fichero_orig= fopen(fich_nombre, "r");
strcpy(fich_dest_nombre, fich_nombre);
sprintf(buffer_nombre, ".00%i", i);
strcat(fich_dest_nombre, buffer_nombre);

fichero_dest = fopen(fich_dest_nombre, "w");
while( ! feof(fichero_orig) )
{
fseek(fichero_orig, pos, SEEK_CUR);
fread( buffer, 1, sizeof(buffer), fichero_orig);

fwrite( buffer, 1, cantidad_por_fich, fichero_dest);
pos += num_partes;
}
fclose(fichero_orig);
}

rir3760

En el calculo de las partes no consideras si el numero de caracteres en el archivo no es múltiplo del tamaño de cada parte, en ese escenario perderías la ultima.

No necesitas de tres llamadas a función para generar el nombre, en su lugar puedes utilizar sprintf de esta forma:
sprintf(fich_dest_nombre, "%s.%03d", fich_nombre, i);

El nombre del archivo generado se almacena en el array "fich_dest_nombre" pero tu llamas a fopen usando el array "fitx_dest_izena", aquí no se si es un error del programa o de traducción. Caso similar con "fitxategi_orig".

Mejor publica el código fuente del programa (reducido al mínimo, por supuesto).

Un saludo
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

NathanD

Cita de: rir3760 en 25 Febrero 2013, 19:13 PM
En el calculo de las partes no consideras si el numero de caracteres en el archivo no es múltiplo del tamaño de cada parte, en ese escenario perderías la ultima.

No necesitas de tres llamadas a función para generar el nombre, en su lugar puedes utilizar sprintf de esta forma:
sprintf(fich_dest_nombre, "%s.%03d", fich_nombre, i);

El nombre del archivo generado se almacena en el array "fich_dest_nombre" pero tu llamas a fopen usando el array "fitx_dest_izena", aquí no se si es un error del programa o de traducción. Caso similar con "fitxategi_orig".

Mejor publica el código fuente del programa (reducido al mínimo, por supuesto).

Un saludo
Ah sí, se me ha ido la cabeza con la traducción del euskera al castellano, jajaja.

NathanD

Cita de: rir3760 en 25 Febrero 2013, 19:13 PM
En el calculo de las partes no consideras si el numero de caracteres en el archivo no es múltiplo del tamaño de cada parte, en ese escenario perderías la ultima.

No necesitas de tres llamadas a función para generar el nombre, en su lugar puedes utilizar sprintf de esta forma:
sprintf(fich_dest_nombre, "%s.%03d", fich_nombre, i);

El nombre del archivo generado se almacena en el array "fich_dest_nombre" pero tu llamas a fopen usando el array "fitx_dest_izena", aquí no se si es un error del programa o de traducción. Caso similar con "fitxategi_orig".

Mejor publica el código fuente del programa (reducido al mínimo, por supuesto).

Un saludo
¿Entonces se trata de que sea múltiplo o no? Entonces, debería primero ver los caracteres que hay en el fichero, y ofrecer al usuario la posibilidad de dividir el archivo en cantidades que sean divisoras del número de caracteres, ¿no?

leosansan

Aunque ya te conteste en el otro foro, por si te sirve ahí va eso:

Cita de: NathanDBuenas, bueno pues después del anterior problema se me presenta éste. Quiero dividir un fichero en varias partes, por ejemplo:

fichero.txt -> fichero.txt.001, fichero.txt.002, fichero.txt.003, etc.

Supongo que habrás querido decir

fichero.txt -> fichero.001.txt, fichero.002.txt, fichero.003.txt, etc.

ya que en caso contrario pierdes el "tipo" de fichero.

Citar
Donde estoy atascado es en dividir el contenido del primer fichero
........................

El bucle principal del código que he hecho es éste, que en lugar de dividir el primer fichero, copia todo el contenido.
........................................

Bueno, yo no soy experto ni en C ni en ficheros ni en nada, pero este código hace lo que pretendes:

Código (cpp) [Seleccionar]

/* Copiador de ficheros a trozos en C*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

  int main()  {
  FILE *fichOrg, *fichDest; /* Los dos ficheros */
  char *buffer; /* El buffer para guardar lo que leo */
  char nombreOrg[80], /* Los nombres de los ficheros */
  nombreDest[80],nombreDest1[80],partes[80];
  long longitud; /* Tamaño del fichero */
  long cantidad; /* El número de bytes leídos */
  int i,num_partes=4;
    /* Accedo al fichero de origen */
    printf("Introduzca el nombre del fichero Origen: ");
    scanf("%s",nombreOrg);
    if ((fichOrg = fopen(nombreOrg, "rb")) == NULL)  {
      printf("No existe el fichero origen!\n");
      exit(1);
    }
    /* Y ahora al de destino */
    printf("Introduzca el nombre del fichero Destino: ");
    scanf("%s",nombreDest);
    strcpy(nombreDest1, nombreDest);

    if ((fichDest = fopen(nombreDest, "wb")) == NULL)  {
      printf("No se ha podido crear el fichero destino!\n");
      exit(2);
    }
    /* Miro la longitud del fichero de origen */
    fseek(fichOrg, 0, SEEK_END);
    longitud = ftell(fichOrg);
    fseek(fichOrg, 0, SEEK_SET);
    if ((fichDest = fopen(nombreDest, "wb")) == NULL)  {
      printf("No se ha podido crear el fichero destino!\n");
      exit(2);
    }
    /* Reservo espacio para leer todo */
    buffer = (char *) malloc (longitud);
    if (buffer == NULL)  {
      printf("No se ha podido reservar tanto espacio!\n");
      exit(3);
    }

    for(i=0; i <num_partes; i++) {
      sprintf(partes, "00%i_", i);
      strcat(partes,nombreDest1 );
      if ((fichDest = fopen(partes, "wb")) == NULL)  {
        printf("No se ha podido crear el fichero destino!\n");
        exit(4);
      }
      /* Leo una parte de los datos a la vez */
      fseek(fichOrg, i*longitud/num_partes, SEEK_SET);
      cantidad = fread( buffer, 1, longitud/num_partes, fichOrg);
      /* Escribo tantos como haya leído */
      fwrite(buffer, 1, cantidad, fichDest);
      if (cantidad != longitud/num_partes)
        printf("Cuidado: no se han leido (ni copiado) todos los datos\n");
      strcpy(nombreDest1, nombreDest);
    }
    /* Cierro los ficheros */
    fclose(fichOrg);
    fclose(fichDest);
    return 0;
}


El secreto está, además de como crear las partes, en "situarse" en una posición y leer hasta ahí para posteriormente escribir y volver al punto dónde nos quedamos y volver a repetir el proceso. O sea, mírate bien la instrucción fseek que ya te había mencionado en el otro tema  ;-)

Saluditos!.

P.D: ¿Me puedes pasar vía "mp" la página de los emoticones?. Gracias.
:laugh:

NathanD

Ya sé por qué no funcionaba mi código, no era más que un error tonto... En cada vuelta del bucle, a la posición del primer carácter que se debía copiar, le sumaba la variable equivocada. Le estaba sumando el número de partes en las que se iba a dividir el fichero, en lugar de la cantidad de caracteres que se debían de copiar a cada ciclo. Es decir, en lugar de
pos += num_partes;

Tenía que poner
pos += cantidad_por_fich

Muchas gracias a todos por vuestra atención, de veras, vuestra dedicación es impagable  ;) ;)