Pequeño error en ficheros

Iniciado por DickGumshoe, 9 Mayo 2012, 17:26 PM

0 Miembros y 1 Visitante están viendo este tema.

DickGumshoe

Hola.

Estoy intentando leer las n últimas líneas de un fichero, para, posteriormente, almacenarlas en otro.

Por ejemplo, si mi fichero tiene:

hola
adiós
duda
ficheros
punteros
estructuras


y meto el número 3 por consola, después de introducir el nombre del fichero, me debería leer:

Citarficheros
punteros
estructuras

Y, sin embargo, me lee:

os
punteros
estructuras


Mi código es:

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

typedef struct{

int *V;
int lineas;

}Estructura;

char* InicializarCadena();
Estructura Contar(FILE *fp);
void Almacenar(FILE *fp1,FILE *fp2,Estructura aux,int n);

int main (){

FILE *fp1;
FILE *fp2;

int n;

char *fich,c;

Estructura aux;

printf("Introduzca el nombre del fichero: ");

fich=InicializarCadena();


printf("Introduce un numero: ");
scanf("%d", &n);

    fp1=fopen(fich, "r");
    fp2=fopen("Trabajo.txt", "w");


    if(fp1==NULL){
    printf("ERROR");
    system("pause");
    exit(1);
    }

    aux=Contar(fp1);


    Almacenar(fp1,fp2,aux,n);

free(aux.V);
free(fich);
fclose(fp1);
fclose(fp2);

system("pause");
}


char* InicializarCadena(){
   int i = 0;
   char c, *cad;

   cad = (char*) malloc(sizeof(char));

   while((c = getchar())!= '\n'){
      cad[i] = c;
      i++;
      cad = (char*)realloc(cad, (i + 1)*sizeof(char));
   }
   cad[i] = '\0';

   return cad;
}

Estructura Contar(FILE *fp){

int i=0;

Estructura aux;

char c;

aux.lineas=0;

aux.V=(int*) malloc(sizeof(int));

while(feof(fp)==0){

c=fgetc(fp);
i++;

if(c=='\n'){
aux.V=(int*) realloc(aux.V,(aux.lineas+1)*sizeof(int));
aux.V[aux.lineas]=i;

aux.lineas++;
}
}
aux.lineas++;
return(aux);
}

void Almacenar(FILE *fp1,FILE *fp2,Estructura aux,int n){

char c;

fseek(fp1,aux.V[aux.lineas-n],SEEK_SET);



while(feof(fp1)==0){

c = fgetc(fp1);
fputc(c,fp2);
printf("%c", c);

}

}


¿Qué hago mal?

Muchas gracias.

Saludos.

durasno

Hola! tratando de ayudart con este problema, vi algo q la verdad no tengo idea de porque pasa. Antes de responderte, primero necesito que ejecutes este codigo
#include <stdio.h>

int main() {
   
    char c;
    int i=0, j=0;
    FILE *fp1=fopen("archivo.txt", "r");
   

    while(j<8){
    c=fgetc(fp1);
    i=ftell(fp1);
   
    printf("i:%d %d %c\n",i,c, c);
    j++;
   
}
    system("PAUSE");
    return 0;
}

El archivo.txt es el q vos tenes con: hola, adios........ Vas a ver q cuando lo ejecutas pasa algo(q hasta 1 min no sabia) interesant. Cuando ftell devuelve 4 se imprime 97 y el caracter 'a', hasta aca bien. Pero en el siguiente ciclo vas a notar que ftell no vale 5(como deberia ser) vale 6 y al lado se imprime el 10 y el salto de linea(ENTER)
La verdad nose xq despues de imprimir 'a', ftell devuelve 6 ¿y el 5??? es como que despues de la 'a' de "hola" hay dos "caracteres": uno nose(seria el 5) y el otro es el enter(el 6)

Sabiendo esto, te dejo modificado la parte del codigo q tendrias mal:
while(feof(fp)==0){

c=fgetc(fp);
i++;

if(c=='\n'){
            i++;// HAY Q AGREGAR UN INCREMENTO ADICIONAL
aux.V=(int*) realloc(aux.V,(aux.lineas+1)*sizeof(int));
aux.V[aux.lineas]=i;

aux.lineas++;
}
}
//aux.lineas++; este incremento estaria demas
return(aux);
}

Agregue un i++ dentro del if, por lo mencionado anteriormente. Comente aux.lineas++; ya q esta demas. Enrealidad no esta demas solo q despues en
fseek(fp1,aux.V[aux.lineas-n],SEEK_SET);
ademas de restarle n tambien tendrias q restarle 1. Acordate q los arreglos van de 0 a n-1

Otra cosa para arreglar es
while(feof(fp1)==0){

c = fgetc(fp1);
fputc(c,fp2);
printf("%c", c);
}

tendria q ser
if((c = fgetc(fp1))!=EOF) // tenes q comprar q no sea EOF
fputc(c,fp2);

ya q vas a guardar un caracter demas(basura en fp2). Tenes q poner ese if ya que en cierto modo estas haciendo mal el ciclo while, primero se lee del archivo luego se comprueba q no sea fin de archivo y se vuelve a leer ....ej:
c=fgetc(fp1); // primero leo del archivo
while(feof(fp1)==0){ // compruebo

fputc(c,fp2); // guardo en fp2
printf("%c", c);
c=fgetc(fp1);  // vuelvo a leer
}


Bueno hasta aca llega lo q pude deducir(bastante interesant aunq me qdo un vacio ya q no entendi xq pasa eso), espero q alguien pueda responder el porque de ftell salta de 4 a 6

Saludos
Ahorrate una pregunta, lee el man

DickGumshoe

Muchas gracias por tu ayuda. Ya he editado el código para que salga bien.

A ver si alguien nos puede explicar por qué pasa eso...

Saludos.