Páginas: [1] 2
|
 |
|
Autor
|
Tema: Explicacion de un Codigo. (Leído 624 veces)
|
^TiFa^
Desconectado
Mensajes: 644
Need a Love Loan? Borrow some from me :)
|
Hola tengo el siguiente codigo ::: #include <stdio.h> #include <stdlib.h>
main(FILE *archivo, int a, int *p) { archivo = fopen("archivo.txt", "r");
if (!archivo) { fprintf(stderr, "No se pudo\n"); clearerr(archivo); exit(1); }
fseek(archivo, 0, SEEK_SET);
a = ftell(archivo); p = malloc(a);
char palabra[*p];
while(!feof(archivo)) {
if (fgets(palabra, *p, archivo)) { printf("%s\n", palabra); } } free(p); return 0; }
El cual funciona perfectamente, lee el archivo he imprime toda la data. Ahora... hay una pequena duda de mi parte si cambio en fseek y en vez de el puntero ubicarse en la linea 0 o antes del primer caracter. hago esto :: fseek(archivo, 0, SEEK_END); Y compilo y ejecuto.. sencillamente no me imprime nada en pantalla, se queda el bucle while ejecutando en background en memoria no ocurre asi si lo hago con 'Seek_SET' pero no deberia puesto que yo quiero asignarle el tamano del archivo a mi puntero *p. Alguien podria mas o menos explicarme porque esta ocurriendo de tal manera... 
|
|
|
|
|
En línea
|
|
|
|
ҒrεακΠιи∂
Desconectado
Mensajes: 101
|
Buenas
Estas segura que ejecuta el while cuando usas SEEK_END???
SEEK_END deberia poner el puntero del archivo en el final del mismo por lo que si lees, deberias estar leyendo el EOF, con lo que el while nunca se ejecutaria.
Saludos, FreakMind
|
|
|
|
|
En línea
|
Connoisseurs of C semantics find C++ inferior to ++C 
|
|
|
Flakito81
Desconectado
Mensajes: 302
|
Lo extraño es que eso compile xDD
1- Parece que desconoces los prototipos normales de la funcion main - int main (void) - int main (int argc, char **argv) - int main (int argc, char **argv, char **env); 2- Cuando abres un fichero, simpre que no sea para añadir, el puntero se posicionará al principio, por lo que el fseek (SEEK_SET) sobra. 3- Si abres un fichero y/o lo posicionas al principio ¿qué crees que devolverá ftell? ¿quizas sea cero? 4- Para que usas un malloc (mal usado sea dicho de paso) ? Un malloc reserva memoria, asi que tendrás un vector de enteros de cero posiciones. 5- char palabra[*p]; ? 5a- Esa linea, bien usada que no es el caso, tiene como objetivo crear un vector de caracteres en tiempo de ejecucion. Es decir tienes que especificarle un valor numerico, ejemplo: 256, 0xff o una constante, pero ha de ser un valor predefinido. Si lo que quieres es que el tamaño se defina en el transcurso del programa has de usar malloc. 5b- Por simple lógica, imaginemos por un segundo que se pudiese hacer esa reserva de memoria y supondremos p no NULL. ¿ que tamaño va a tener el vector? xq me temo que es totalmente desconocido xq no lo has inicializado y en ese trozo de código lo único que haría sería reservar un vector del tamaño que tenga la primera celda de p (valor al que apunta p) 6- que sentido tiene posicionar el puntero del fichero al final si lo q pretendes es leer? 7- los ficheros después de usarlos hay que cerrarlos.
Lo mismo el código podría funcionarte haciendo unos cambios: 1- Cambiar el prototipo del main. 2- abrir el fichero con el control de errores blablabla 3- posicionarte al final del fichero 4- usar el ftell y guardar el valor de retorno 5- posicionarte al principio del fichero con el fseek 6- usar el valor devuelto por ftell para reservar una cadena de caracteres con malloc 7- hacer un bucle con la condicion de que no se llege a final de fichero, ya lo tienes hecho. 8- cambiar el fgets por fread, por ejemplo, ya que fgets se para cada vez que llega al final de una linea. 9- una vez se sale del bucle liberar memoria y cerrar fichero.
Suerte!
|
|
|
|
« Última modificación: 14 Mayo 2008, 02:14 por Flakito81 »
|
En línea
|
|
|
|
winfuck
Desconectado
Mensajes: 253
|
main(FILE *archivo, int a, int *p)
bueno sin entrar en detalles sobre como te has echado por culo los estandares, sigamos con los problemas que pides solucion. fseek(archivo, 0, SEEK_SET);
deberias estudiar mas las funciones basicas, si lo que queres es desplasarte hacia el final del fichero para saber su longitud y luego reserver memoria, deberias usar SEEK_END, ya que SEEK_SET indica el comienso del fichero, y en esa sentencia no te has movido. pero creo que de esto ya te habias dado cuenta no? bueno si estas reservando memoria para luego leer un fichero, deberia ser un puntero a char, no a int. OMFG :S deberia dejar de ayudarte y mandarte a leer un libro , pero hoy estoy bueno. no sabemos que hay donde apunta p, hasi que eso esa sentencia es muy peligrosa, ya que p puede apuntar a cualquier cosa, aparte si ya asignaste toda la longitud del fichero en p, para que queres otra variable oO! jamas uses feof de ese modo en un bucle. el problema esta en feof, como calcula el final del fichero, aca te dejo lo que dice el estandard para que veas: 7.19.10.2 The feof function
Synopsis
1 #include <stdio.h> int feof(FILE *stream);
Description 2 The feof function tests the end-of-file indicator for the stream pointed to by stream.
Returns 3 The feof function returns nonzero if and only if the end-of-file indicator is set for stream.
if (fgets(palabra, *p, archivo)) {
otra ves, me parece que no sabes lo que haces, fgets (char *fgets(char *s, int size, FILE *stream)) como veras el 2º argumento que pasas no sabes bien que es, ya lo discuti mas arriba, fgets lee como maximo uno menos que el numero de caracteres indicado por size. explicado eso, te dejo un ejemplo de lo que creo que quieres hacer: este ejemplo lee cada linea del fichero y la muestra. #include <stdio.h> #include <stdlib.h>
#define MAX_BUFF 81
int main(int argc, char **argv) { FILE *fp;
if ((fp=fopen(argv[1], "r"))==NULL) { perror("Error"); exit(1); }
char pal[MAX_BUFF];
while(fgets(pal, 81, fp) != NULL) /*Lee max. 80 caracteres por linea.*/ printf("%s", pal);
fclose(fp);
return 0; }
este ejemplo carga todo el fichero en memoria y luego lo imprime. #include <stdio.h> #include <stdlib.h>
int main(int argc, char** argv) {
char* buffer; long fileSize = 0;
FILE* test; test = fopen(argv[1], "r");
fseek(test, 0, SEEK_END); fileSize = ftell(test); rewind(test);
printf("Size= %ld\n", fileSize);
buffer = malloc(sizeof(char) * fileSize); fread(buffer, 1, fileSize, test); fclose(test);
printf("File\n----------\n%s", buffer);
return 0; }
espero que esos ejemplos te sean util. cya
|
|
|
|
« Última modificación: 14 Mayo 2008, 02:23 por winfuck »
|
En línea
|
|_|0|_| |_|_|0| |0|0|0|
|
|
|
^TiFa^
Desconectado
Mensajes: 644
Need a Love Loan? Borrow some from me :)
|
Gracias por las explicaciones..... Un poco despectivos pero ni modo, diariamente enfrento personas asi.  Yo pensaba... y sigo pensando que alguien me lo aclare. Que cuando asignas un valor a un puntero, para acceder a ese valor debo hacerlo asi *p no asi p. O al menos asi lo he leido en el libro de C que leo, asi que ignorantemente de mi parte a lo mejor, aun sabiendo que seek_set y seek_cur devuelven cero, quize asignarselo a la variable char palabra[0] argumentandolo asi char palabra[*p] Que alguien me muestre un ejemplo de asignarle el valor de un puntero como espacio a una variable char. Otra pregunta, porque no puedo declarar otros parametros en main que no sean los predefinidos int argv, char argc ???
|
|
|
|
« Última modificación: 14 Mayo 2008, 16:42 por ^TiFa^ »
|
En línea
|
|
|
|
^TiFa^
Desconectado
Mensajes: 644
Need a Love Loan? Borrow some from me :)
|
Olvidenlo... ya encontre la respuesta a mi pregunta por mi cuenta. Como dijiste Winfuck.. el problema esta en feof  me habia confundido con EOF y feof y no recordaba que hacia cada uno lol  no puedo usar esto while(!feof(archivo)) y a la vez usar seek_end  ignorancia de mi parte... sorry. Creo que ya me respondi.  Gracias por recordarme flakito01 a cerrar el archivo, siempre se me pasa siempre.
|
|
|
|
|
En línea
|
|
|
|
^TiFa^
Desconectado
Mensajes: 644
Need a Love Loan? Borrow some from me :)
|
Igual quite los parametros 'extras' de la funcion main. Aunque insisto, quiero una explicacion sobre porque no puedo usar otros parametros en main que no sean solo argc, y argv... No quiero respuestas tipo : Porque es el estandar. Porque no tendra portabilidad el programa. Quiero algo con logica,  Este es el codigo mejorado un poquito supongo. #include <stdio.h> #include <stdlib.h> #include <signal.h>
int main(void) {
FILE *fp; register int *p; int b;
if(!(fp = fopen("archivo.txt", "r"))) { fprintf(stdout, "Error No existe\n"); clearerr(fp); raise(SIGTERM); }
fflush(stdout);
fseek(fp, 0, SEEK_END); b = ftell(fp); p = &b;
char a[*p];
rewind(fp);
while(!feof(fp)) { if(fgets(a, *p, fp)) { fprintf(stdout, "%s\n", a); } }
fclose(fp); return 0; }
|
|
|
|
|
En línea
|
|
|
|
Ferсhu
Desconectado
Mensajes: 1.214
Menos palabras y Mas codigos.
|
b = ftell(fp); p = &b;
char a[*p]; Nose q flashaste aca pero eso no se puede, ya te lo dijeron. Usa malloc, lo raro q a freeze le puse un ejemplo en otro post y vos contestaste a ese, pensaba q habias visto lo q le habia dicho a el. Si keres leer el tamaño de un archivo y guardar su contenido una posiblidad es esta: int tam; char *buffer; fseek(file, 0, SEEK_END); // vas al final del archivo tam = ftell(file); // obtenes la ultima pos, q ekivale al tamaño buffer=(char *)malloc(tam); // pedis esa cantidad de memoria fseek(file, 0, 0); // volves al principio para poder leer todo fread(buffer,tam,1,file); // lees todo el archivo y lo guardas en el buffer. fclose(file); o tambien en vez de fread podes con: while(!feof(file)){ buffer[i]=getc(file); i++ }
|
|
|
|
|
En línea
|
|
|
|
Eternal Idol
Desconectado
Mensajes: 1.263
Assembly (x86/x64), C/C++, Kernel Mode (WDM/WDF)
|
Igual quite los parametros 'extras' de la funcion main. Aunque insisto, quiero una explicacion sobre porque no puedo usar otros parametros en main que no sean solo argc, y argv... No quiero respuestas tipo : Porque es el estandar. Porque no tendra portabilidad el programa. Quiero algo con logica,  Sea quien sea que llame al main tiene una convencion y esa no implica mas que los parametros ya conocidos. En GNU/Linux es el propio Kernel el encargado de pasar los parametros en la pila y estos son argc, argv y envp. En Windows la RTL hace el mismo trabajo.
|
|
|
|
|
En línea
|
be closely tied to (v.) = estar estrechamente ligado a Ex: He had been wrapped up in a new project that was closely tied to the company's new growth.
"La economia nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de este" Juan Domingo Peron
|
|
|
^TiFa^
Desconectado
Mensajes: 644
Need a Love Loan? Borrow some from me :)
|
Hola nuevamente. Quiero saber realmente porque no se puede esto ::: b = ftell(fp); p = &b;
char a[*p];
Puesto que expuesto de esa forma, el puntero p vale lo que obtuvo b, ahora si hago esto :: p = malloc(b); Me temo que tendre nada, (Ya lo probe anteriormente). Cuando lo hago asi, obtengo una direccion de memoria no un valor. Pero si lo hago como expuse arriba obtengo el valor de b ya que apunto a su direccion en memoria y si hago : printf("%d", *p); Me doy cuenta que *p vale realmente lo que obtuvo b con ftell, pero si lo hago con malloc... *p me devuelve cero. Entonces se me dijo que en este trozo : char a[*p]; Estaba mal, porque *p en este caso valia 0 y no tiene logica asignarle a una variable char un buffer de 0 caracteres... lo cual es logico. Pero si *p ya tiene el valor real de 'b' porque esta mal asignarselo a la variable a??? si ya *p tiene realmente un valor definido???. Esta muy bien las dos explicaciones que exponen sobre como asignar memoria dinamica, pero asi como hay 2 maneras pueden haber 3 o 4 o 5 maneras de asignar el valor de un archivo y no precisamente siempre usando 'malloc' Creo que C tiene mil formas de hacer las cosas, solo hay que reinventar un poco. La razon por la cual esta aparentemente mal mi trozo de codigo... Porque segun se sale del estandar ... verdaderamente, no creo que este mal tecnicamente asignarle a main mas parametros o parametros extras en que parte de C dicen que esto no se puede? O en que parte de C se dice que no puedo asignarle el valor de una variable a un puntero y usar el valor de ese puntero como almacenamiento de una variable de caracteres???? No es el estandar eso se entiende... pero en que parte se dice que no se puede? Y en este codigo Ferchu : fseek(file, 0, SEEK_END); // vas al final del archivo tam = ftell(file); // obtenes la ultima pos, q ekivale al tamaño buffer=(char *)malloc(tam); // pedis esa cantidad de memoria fseek(file, 0, 0); // volves al principio para poder leer todo fread(buffer,tam,1,file); // lees todo el archivo y lo guardas en el buffer. fclose(file);
A lo mejor soy yo pero percibo que hago doble trabajo  o sea leo el archivo, almaceno, asigno, vuelvo al inicio del archivo , para volver a almacenar para volver a asignar.... No se, no se, pero realmente me ahorro mas codigo de la forma irracional que lo hice al principio.
|
|
|
|
« Última modificación: 16 Mayo 2008, 18:46 por ^TiFa^ »
|
En línea
|
|
|
|
Eternal Idol
Desconectado
Mensajes: 1.263
Assembly (x86/x64), C/C++, Kernel Mode (WDM/WDF)
|
verdaderamente, no creo que este mal tecnicamente asignarle a main mas parametros o parametros extras en que parte de C dicen que esto no se puede? Segui haciendolo asi, se nota que sos una verdadera hard-hand-scripter ftell.
|
|
|
|
« Última modificación: 16 Mayo 2008, 18:52 por Eternal Idol »
|
En línea
|
be closely tied to (v.) = estar estrechamente ligado a Ex: He had been wrapped up in a new project that was closely tied to the company's new growth.
"La economia nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de este" Juan Domingo Peron
|
|
|
^TiFa^
Desconectado
Mensajes: 644
Need a Love Loan? Borrow some from me :)
|
Lo siento, a lo mejor soy un poco terca  pero ahora mismo me siento como : Tifa :: Quiero usar amarok en Gnome. Gente :: No se puede. Tifa :: Porque no puedo? Gente :: Porque amarok no viene tecnicamente para funcionar en Gnome. Tifa :: Pero puedo bajarme QT3 para usar amarok en Gnome. Gente :: NO, NO, no se puede! se sale del estandar Gnome, por eso Gnome trae GTK+ Lo siento,  solo que creo que hay muchas maneras de hacer las cosas y me gustaria ir conociendo mas maneras de hacerlas, no solo las ya predefinidas o estandares. Se ve muy mecanico. Y si soy muy hand-scripting.
|
|
|
|
|
En línea
|
|
|
|
Eternal Idol
Desconectado
Mensajes: 1.263
Assembly (x86/x64), C/C++, Kernel Mode (WDM/WDF)
|
La situacion en realidad es asi, tu main va a ser llamado con 3 parametros en la pila que siempre van a ser los mismos (un int con el numero de argumentos en linea de comandos, un doble puntero a char con los argumentos en lineas de comandos, y un doble puntero a char con las variables del entorno). Si tenes ganas podes poner mas parametros en tu main y cambiarle los nombres y los tipos. No sirve para nada y es una estupidez.
Y lo de hard-hand-scripter supongo que tambien lo decis en broma, esta claro que no tenes mucha idea de lo que estas haciendo.
|
|
|
|
|
En línea
|
be closely tied to (v.) = estar estrechamente ligado a Ex: He had been wrapped up in a new project that was closely tied to the company's new growth.
"La economia nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de este" Juan Domingo Peron
|
|
|
^TiFa^
Desconectado
Mensajes: 644
Need a Love Loan? Borrow some from me :)
|
Tambien aprecio todo tipos de opiniones Eternal Idol sean buenas o sean malas. 
|
|
|
|
|
En línea
|
|
|
|
Ferсhu
Desconectado
Mensajes: 1.214
Menos palabras y Mas codigos.
|
se me habia olvidado de aclararte lo del main jaja pero ya te lo aclararon. La respuesta corta y practica seria, si no vas a usar los parametros esos da igual como lo declares. Lo demas ya te lo dijeron. Quiero saber realmente porque no se puede esto :::
Código:
b = ftell(fp); (1) p = &b; (2)
char a[*p]; (3)
(1) Ahi perefecto, guarda la posicion actual en el archivo. (2) ahi guardas la direccion de b en p q es un puntero, entonces decir "p" o decir "b" es lo mismo (siendo p un puntero al mismo tipo de variable). Eso no tiene mucho sentido. (3) ahi estas declarando estaticamente un vector "a" de longuitud "contenido de p", eso no tiene sentido ni coherencia, por q se declara una variable estatica, eso kiere decir q al compilarlo se deja lugar en la pila para esa variable, y el contenido de p no se conoce hasta q no se haya ejecutado el codigo del programa. Ademas siguiendo tu logica, la resbuscas mucho x q lo q pusiste seria lo mismo q char a[ b] o char a[ftell(fp)], pero eso no se puede hacer, aun asi no entiendo por q kisiste meter punteros de por medio. Las variables estaticas tiene lugar en la pila, y el compilador se encarga de acomodar el codigo para q "existan" dichos tamaños. las variables dinamicas lo unico q hay en la pila son los punteros q hacen referencia a su posicion de memoria, la memoria donde se guardan los datos esta fuera de la pila, y es allocada por el SO en el espacio disponible del programa.
|
|
|
|
|
En línea
|
|
|
|
|
Páginas: [1] 2
|
|
|
|