problema leyendo archivos en C

anomalie
03 de Julio del 2009
Hola
Intento utilizar este codigo para leer un archivo introduciendo el nombre del archivo en tiempo de ejecucion

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

int main () {
char arch[20];
char texto[200];
printf("nnEscriba el nombre del archivo que desee leer: ");
scanf("%s",&arch);
printf("nnAbriendo archivo %s ...nn",arch);
system("pause>nul");

FILE *fp;
fp = fopen(arch,"r");
if (fp==NULL)
printf("nnError al abrir el archivo. Presione una tecla para salir.");
system("pause>nul");
exit (1);
while (feof(fp)==0) {
fgets(texto,200,fp);
printf("%s",texto);
}
system("pause>nul");
return 0;
}


Tengo un archivo prueba.txt y todo eso bien. Cuando intento abrir un archivo que no existe me sale el mensaje de error que le puse y se cierra, pero cuando intento abrir el archivo que si existe no me sale nada. Llega directamente al pause del final y se cierra en cuanto toco algo. :S

Alguna ayuda ?

PD: Si, soy nuevo xD

Un saludo

Jormar Arellano
03 de Julio del 2009
Fijate, hay algunos detalles que comentar para los tengas en cuenta:

Cuando declaras array's ( char arch[20] ), en realidad, estas declarando punteros constantes a memoria, por lo que, si quieres referenciar la primera posicion a la que apunta, es redundante (e incorrecto) hacer &arch, en lugar de ello escribe solamante arch (que es lo mismo que &arch[0]), Otra cosa al respecto es que, al hacer char arch[20] limitas las lecturas a archivos cuyo nombre sea menor a 19 caracteres (necesitas el otro para ''), para ello, te recomiendo que cambies la declaracion a char *arch.

Ahora, cuando usas la funcion system, debes tener cuidado, ya generas conflicots de compactibilidad (por ejemplo, yo no tengo ningun comando por consola llamado pause). Si quieres parar la ejecucion hasta que el usuario presione una tecla, usa por ejemplo la función getchar() (incluida en stdio.h).

El problema en concreto que tienes son los corchetes del if (fp == NULL): solo incluyes a printf, dejando por fuera el system y exit poseriores.

Otra cosa es que gets() solo te lee, a lo sumo, una linea... si yo engo 10000 lineas de un solo caracter, entonces tomaría solo dos caracteres por lectura (el caracer y el 'n'), por lo que la gracia de un buffer de 200 caracteres se pierde; te recomiendo usar fread() en lugar de fgets().

Otra cosa con eof(), cuando lees la ultima linea del archivo, es posible que se trate de una linea en blanco, con lo cual fgets() te la guarda (pero aun no llega al final del archivo), luego ejecuas feof() que te dice que no has terminado, luego viene fgets() y cuando trata de leer se da cuena que viene el EOF, asi que no guarda nada en tu buffer... "E IMPRIMES NUEVAMENTE LA ULIMA LINEA (Lo que tenia el buffer de la ultima lecura).

Aqui te pongo una solución que corrige todos esos detalles

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

int main () {
// char arch[20]; <- codigo anterior
char *arch; // Con esto no nos importa el tamaño del nombre del archivo
char texto[200];

printf("nnEscriba el nombre del archivo que desee leer: ");
// scanf("%s",&arch); <- codigo anterior
scanf("%s", arch);

printf("nnAbriendo archivo %s ...nn",arch);
// system("pause>nul"); <- codigo anterior
getchar();

FILE *fp;
fp = fopen(arch,"r");
if (fp==NULL) {
printf("nnError al abrir el archivo. Presione una tecla para salir.");
getchar();
// system("pause>nul");
exit (1);
} else {
// while (feof(fp)==0) <- codigo anterior
while( fgets(texto,200,fp) ){
printf("%s",texto);
}
}
// system("pause>nul"); <- codigo anterior
gechar();
return 0;
}




anomalie
03 de Julio del 2009
Joder, pues lo has clavao con la respuesta.
Me han venido muy bien algunas aclaraciones.
Gracias.