elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.
 
Inicio Ayuda Ingresar Registrarse
12 Octubre 2008, 18:38  



+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++
| | |-+  Explicacion de un Codigo.
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] 2 Ir Abajo Imprimir
Autor Tema: Explicacion de un Codigo.  (Leído 712 veces)
^TiFa^

Desconectado Desconectado

Mensajes: 673


Need a Love Loan? Borrow some from me :)


Ver Perfil
Explicacion de un Codigo.
« en: 13 Mayo 2008, 23:40 »

Hola tengo el siguiente codigo :::

Código:
#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 ::

Código:
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

http://chixmes.blogspot.com/

Si quieres saber el valor del dinero, trata de conseguirlo prestado. 

El que se enorgullece de sus conocimientos es como si estuviera ciego en plena luz.
- Benjamin Franklin.

ҒrεακΠιи∂

Desconectado Desconectado

Mensajes: 121



Ver Perfil
Re: Explicacion de un Codigo.
« Respuesta #1 en: 14 Mayo 2008, 01:46 »

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 Desconectado

Mensajes: 350



Ver Perfil
Re: Explicacion de un Codigo.
« Respuesta #2 en: 14 Mayo 2008, 02:11 »

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 Desconectado

Mensajes: 254



Ver Perfil
Re: Explicacion de un Codigo.
« Respuesta #3 en: 14 Mayo 2008, 02:12 »

Código:
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.

Código:
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?

Código:
p = malloc(a);
bueno si estas reservando memoria para luego leer un fichero, deberia ser un puntero a char, no a int.

Código:
char palabra[*p];
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!

Código:
while(!feof(archivo)) {
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:

Citar
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.

Código:
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.
Código:
#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.
Código:
#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 Desconectado

Mensajes: 673


Need a Love Loan? Borrow some from me :)


Ver Perfil
Re: Explicacion de un Codigo.
« Respuesta #4 en: 14 Mayo 2008, 16:14 »

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

http://chixmes.blogspot.com/

Si quieres saber el valor del dinero, trata de conseguirlo prestado. 

El que se enorgullece de sus conocimientos es como si estuviera ciego en plena luz.
- Benjamin Franklin.

^TiFa^

Desconectado Desconectado

Mensajes: 673


Need a Love Loan? Borrow some from me :)


Ver Perfil
Re: Explicacion de un Codigo.
« Respuesta #5 en: 14 Mayo 2008, 16:33 »

Olvidenlo... ya encontre la respuesta a mi pregunta por mi cuenta.

Como dijiste Winfuck.. el problema esta en feof  :o me habia confundido con EOF y feof y no recordaba que hacia cada uno lol  :rolleyes:

no puedo usar esto while(!feof(archivo)) y a la vez usar seek_end  :¬¬  ignorancia de mi parte... sorry.

Creo que ya me respondi.  :D  Gracias por recordarme flakito01 a cerrar el archivo, siempre se me pasa siempre.
En línea

http://chixmes.blogspot.com/

Si quieres saber el valor del dinero, trata de conseguirlo prestado. 

El que se enorgullece de sus conocimientos es como si estuviera ciego en plena luz.
- Benjamin Franklin.

^TiFa^

Desconectado Desconectado

Mensajes: 673


Need a Love Loan? Borrow some from me :)


Ver Perfil
Re: Explicacion de un Codigo.
« Respuesta #6 en: 16 Mayo 2008, 07:15 »

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, :P

Este es el codigo mejorado un poquito supongo.

Código:
#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

http://chixmes.blogspot.com/

Si quieres saber el valor del dinero, trata de conseguirlo prestado. 

El que se enorgullece de sus conocimientos es como si estuviera ciego en plena luz.
- Benjamin Franklin.

Ferсhu

Desconectado Desconectado

Mensajes: 1.221

Menos palabras y Mas codigos.


Ver Perfil WWW
Re: Explicacion de un Codigo.
« Respuesta #7 en: 16 Mayo 2008, 08:08 »

Citar
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:

Código:
       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:

Código:
while(!feof(file)){
buffer[i]=getc(file);
i++
}


En línea

Eternal Idol N&P

Desconectado Desconectado

Mensajes: 1.345


Assembly (x86/x64), C/C++, Kernel Mode (WDM/WDF)


Ver Perfil WWW
Re: Explicacion de un Codigo.
« Respuesta #8 en: 16 Mayo 2008, 09:58 »

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, :P

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

http://www.nacionalypopular.com/
http://www.lucheyvuelve.com.ar/

"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 Desconectado

Mensajes: 673


Need a Love Loan? Borrow some from me :)


Ver Perfil
Re: Explicacion de un Codigo.
« Respuesta #9 en: 16 Mayo 2008, 18:42 »

Hola nuevamente.

Quiero saber realmente porque no se puede esto :::

Código:
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 :

Código:
  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

http://chixmes.blogspot.com/

Si quieres saber el valor del dinero, trata de conseguirlo prestado. 

El que se enorgullece de sus conocimientos es como si estuviera ciego en plena luz.
- Benjamin Franklin.

Eternal Idol N&P

Desconectado Desconectado

Mensajes: 1.345


Assembly (x86/x64), C/C++, Kernel Mode (WDM/WDF)


Ver Perfil WWW
Re: Explicacion de un Codigo.
« Respuesta #10 en: 16 Mayo 2008, 18:50 »

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  :rolleyes:

ftell.
« Última modificación: 16 Mayo 2008, 18:52 por Eternal Idol » En línea

http://www.nacionalypopular.com/
http://www.lucheyvuelve.com.ar/

"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 Desconectado

Mensajes: 673


Need a Love Loan? Borrow some from me :)


Ver Perfil
Re: Explicacion de un Codigo.
« Respuesta #11 en: 16 Mayo 2008, 19:08 »

Lo siento, a lo mejor soy un poco terca  :rolleyes: 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,  :P 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

http://chixmes.blogspot.com/

Si quieres saber el valor del dinero, trata de conseguirlo prestado. 

El que se enorgullece de sus conocimientos es como si estuviera ciego en plena luz.
- Benjamin Franklin.

Eternal Idol N&P

Desconectado Desconectado

Mensajes: 1.345


Assembly (x86/x64), C/C++, Kernel Mode (WDM/WDF)


Ver Perfil WWW
Re: Explicacion de un Codigo.
« Respuesta #12 en: 16 Mayo 2008, 19:35 »

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

http://www.nacionalypopular.com/
http://www.lucheyvuelve.com.ar/

"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 Desconectado

Mensajes: 673


Need a Love Loan? Borrow some from me :)


Ver Perfil
Re: Explicacion de un Codigo.
« Respuesta #13 en: 16 Mayo 2008, 19:55 »

Tambien aprecio todo tipos de opiniones Eternal Idol sean buenas o sean malas.

 :-*
En línea

http://chixmes.blogspot.com/

Si quieres saber el valor del dinero, trata de conseguirlo prestado. 

El que se enorgullece de sus conocimientos es como si estuviera ciego en plena luz.
- Benjamin Franklin.

Ferсhu

Desconectado Desconectado

Mensajes: 1.221

Menos palabras y Mas codigos.


Ver Perfil WWW
Re: Explicacion de un Codigo.
« Respuesta #14 en: 16 Mayo 2008, 21:06 »

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.

Citar
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 Ir Arriba Imprimir 
Ir a:  







Consolas     La Web de Goku     MilW0rm     MundoDivx

Hispabyte     Truzone     TodoReviews     ZonaPhotoshop

hard-h2o modding    Foros de ayuda    Yashira.org    Videojuegos    indetectables.net   

Noticias Informatica    Seguridad Informática    ADSL    Foros en español    eNYe Sec

Todas las webs afiliadas están libres de publicidad engañosa.

Powered by SMF 1.1.6 | SMF © 2006-2008, Simple Machines LLC
Free counter and web stats