Seguimos buscando a Arshak. Ayudanos compartiendo!
Encuesta no oficial de docentes
Resultados de la encuesta no oficial de docentes
Probaste el SIGA Helper?

Donar $100 Donar $200 Donar $500 Donar mensualmente


Enviar respuesta 
 
Calificación:
  • 0 votos - 0 Media
  • 1
  • 2
  • 3
  • 4
  • 5
Buscar en el tema
Consulta Ej. 2 de la guia operativos
Autor Mensaje
agusbrand Sin conexión
Profesor del Modulo A
me recibiiiiiiiiiiiiiiiiiiiiii...
*****

Ing. en Sistemas
Facultad Regional Buenos Aires

Mensajes: 233
Agradecimientos dados: 121
Agradecimientos: 60 en 21 posts
Registro en: Dec 2010
Mensaje: #1
Consulta Ej. 2 de la guia operativos Ejercicios Sistemas Operativos
Estoy practicando C con mi grupo antes de cursar , y quisiera saber si esta bien encarado el ejercicio de la guia:

Ejercicio 2 (Modelado de TADs)
Se pide modelar un TAD que represente un Archivo, se debe poder abrir (definir la forma: read/write/append), cerrar un archivo, leer una linea determinada, exponer una operación que reciba una función y la ejecute por cada línea del archivo; exponer otra operación que dada una lista y una función, itere la lista y escriba sobre el archivo abierto.

Guia: https://docs.google.com/document/d/1n_u1...edit?pli=1



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

typedef FILE ARCHIVO;
ARCHIVO *abrir(char *nombre, char *modo);
int cerrar(ARCHIVO *p);
char *leerlinea(char *linea, int maxlinea, ARCHIVO *p);
void operacion( unsigned int(*f)(const char *) , ARCHIVO *p);

int main(void){

ARCHIVO *fp;

char *linea=(char *)malloc(sizeof(char)*1000);
char *linealeida=(char *)malloc(sizeof(char)*1000);

if((fp=abrir("prueba.txt", "leer"))==NULL){
fprintf(stderr, "no se pudo abrir");
exit(1);
}

printf("Ya esta abierto, y ahora leo la primer linea\n");

if((linealeida=leerlinea(linea, 1000, fp))==NULL){
fprintf(stderr, "no se pudo leer linea");
exit(1);
}

printf(" la linea era: %s \n", linealeida);

printf("Ahora hago la operacion mandando la funcion strlen: \n");

operacion(strlen, fp);

cerrar(fp);

free(linea);
free(linealeida);

printf("ya se cerro\n");

return 0;
}



ARCHIVO *abrir(char *nombre, char *modo){

if(strcmp(modo, "leer")==0)
return fopen(nombre,"r");

if(strcmp(modo, "escribir")==0)
return fopen(nombre,"w");

if(strcmp(modo, "apend")==0)
return fopen(nombre,"a");

fprintf(stderr, "Modo mal escrito, hay 3: leer, escribir, o apend");
exit(1);
}


int cerrar(ARCHIVO *p){

return fclose(p);

}


char *leerlinea(char *linea, int maxlinea, ARCHIVO *p){

return fgets(linea, maxlinea, p);
}


void operacion( unsigned int(*f)(const char *) , ARCHIVO *fp){

char *l=(char *)malloc(sizeof(char)*1000);
char *leida=(char *)malloc(sizeof(char)*1000);


while((leida=leerlinea(l, 1000, fp))!=NULL)
printf("%d \n", (*f)(leida) );

free(l);
free(leida);


return;
}




Lo probamos con un archivo prueba.txt con algunas lineas y todo anda bien, lo que faltaria es hacer un .h para el typedef y los prototipos de función calculamos

Muchas Gracias!
(Este mensaje fue modificado por última vez en: 20-03-2014 23:35 por agusbrand.)
20-03-2014 23:33
Envíale un email Encuentra todos sus mensajes Agregar agradecimiento Cita este mensaje en tu respuesta
Virus Sin conexión
Profesor del Modulo A
Programador
*****

Ing. en Sistemas
Facultad Regional Buenos Aires

Mensajes: 361
Agradecimientos dados: 37
Agradecimientos: 60 en 46 posts
Registro en: Feb 2012
Mensaje: #2
RE: Consulta Ej. 2 de la guia operativos
para empezar estan usando memoria dinamica al pedo, la gracia de usar memoria dinamica es pedir una cantidad de memoria que no se conoce hasta tiempo de ejecucion, por lo tanto deberian usar memoria estatica (porque ya saben de antemano cuanta memoria van a utilizar) char linea[1000]; y char linealeida[1000];

otra recomendacion es que no dejen numeros magicos en el programa si van a poner 1000 hagan un define

#define MAX_LINE 1000
21-03-2014 00:32
Encuentra todos sus mensajes Agregar agradecimiento Cita este mensaje en tu respuesta
[-] Virus recibio 1 Gracias por este post
agusbrand (21-03-2014)
dezine18 Sin conexión
Militante
Sin estado :(
***

Ing. en Sistemas
Facultad Regional Buenos Aires

Mensajes: 52
Agradecimientos dados: 1
Agradecimientos: 44 en 21 posts
Registro en: Oct 2008
Mensaje: #3
RE: Consulta Ej. 2 de la guia operativos
Esta encarado, pero le veo un par de inconvenientes técnicos como teoricos:

Un TAD en general se tiene un .h con las operaciones que expone y un .c que las implementa, entonces deberías tener 3 archivos en este caso, el main.c, el archivo.h y archivo.c. Una convención que capaz te sirva para identificar rápidamente que funciones son de un tad y no de la lib estandar es usar la siguiente nomenclatura. <nombre_tad>_<operacion>, igual esto es solo una convención. Seguramente pusiste todo junto para postearlo, así que no hay drama.

Problema técnico, el leerLinea avanza el puntero dentro del archivo, por lo tanto si luego llamas a la función operacion (nombre mas expresivo, podría ser, iterar_lineas ;) ), entonces esta va a iterar sobre las siguientes lineas, y en realidad debe aplicarse a todas las lineas del archivo. Capaz entonces no debería recibir el file abierto, sino un path, ya que no tendría que realizar ninguna operación que tenga efecto sobre el archivo

Este código tiene un par de inconvenientes

char *l=(char *)malloc(sizeof(char)*1000);
char *leida=(char *)malloc(sizeof(char)*1000);
while((leida=leerlinea(l, 1000, fp))!=NULL)
printf("%d \n", (*f)(leida) );

free(l);
free(leida);



Para leída no hace falta reservar memoria, ya que si te fijas el fgets(..) devuelve el parametro que le pasas para que escriba o NULL, por lo tanto te estaría devolviendo la memoria que reservaste en l y la que reservaste en leida se pierde en el limbo de la memoria (lo que se conoce como leak), además si l y leida apuntan a lo mismo, entonces el primer free todo bien, pero cuando hagas el segundo free va a chillar diciendo flaco ya liberaste esta memoria ;)

Una duda, donde lo probaste, linux o windows? porque en general los doble free explotan rápido en linux =)

A una cosa más, si tenes una cantidad definida de valores, podes usar enums(http://stackoverflow.com/questions/11025...-enum-in-c) en vez de strings
(Este mensaje fue modificado por última vez en: 21-03-2014 00:56 por dezine18.)
21-03-2014 00:43
Encuentra todos sus mensajes Agregar agradecimiento Cita este mensaje en tu respuesta
[-] dezine18 recibio 1 Gracias por este post
agusbrand (21-03-2014)
agusbrand Sin conexión
Profesor del Modulo A
me recibiiiiiiiiiiiiiiiiiiiiii...
*****

Ing. en Sistemas
Facultad Regional Buenos Aires

Mensajes: 233
Agradecimientos dados: 121
Agradecimientos: 60 en 21 posts
Registro en: Dec 2010
Mensaje: #4
RE: Consulta Ej. 2 de la guia operativos
Cita:Esta encarado, pero le veo un par de inconvenientes técnicos como teoricos:

Un TAD en general se tiene un .h con las operaciones que expone y un .c que las implementa, entonces deberías tener 3 archivos en este caso, el main.c, el archivo.h y archivo.c. Una convención que capaz te sirva para identificar rápidamente que funciones son de un tad y no de la lib estandar es usar la siguiente nomenclatura. <nombre_tad>_<operacion>, igual esto es solo una convención. Seguramente pusiste todo junto para postearlo, así que no hay drama.

Hice todo junto para entenderme y después iba a hacer la división de los archivos como vos decis en main.c archivo.h archivo.c

Cita:Problema técnico, el leerLinea avanza el puntero dentro del archivo, por lo tanto si luego llamas a la función operacion (nombre mas expresivo, podría ser, iterar_lineas ;) ), entonces esta va a iterar sobre las siguientes lineas, y en realidad debe aplicarse a todas las lineas del archivo. Capaz entonces no debería recibir el file abierto, sino un path, ya que no tendría que realizar ninguna operación que tenga efecto sobre el archivo

Esto lo tenia en cuenta y me olvide de comentarlo, al ejecutar la función operación, itera desde la 2da linea como decis, porque se me dio por probar todo junto y hice lio !

Cita:Este código tiene un par de inconvenientes

char *l=(char *)malloc(sizeof(char)*1000);
char *leida=(char *)malloc(sizeof(char)*1000);
while((leida=leerlinea(l, 1000, fp))!=NULL)
printf("%d \n", (*f)(leida) );

free(l);
free(leida);



Para leída no hace falta reservar memoria, ya que si te fijas el fgets(..) devuelve el parametro que le pasas para que escriba o NULL, por lo tanto te estaría devolviendo la memoria que reservaste en l y la que reservaste en leida se pierde en el limbo de la memoria (lo que se conoce como leak), además si l y leida apuntan a lo mismo, entonces el primer free todo bien, pero cuando hagas el segundo free va a chillar diciendo flaco ya liberaste esta memoria ;)

Una duda, donde lo probaste, linux o windows? porque en general los doble free explotan rápido en linux =)

Claro, entiendo el problema,pero me estoy volviendo loco porque probe en linux(eclipse), y windows y no me salta el problema tener muchos free a la misma cosa. Hasta probe poner tres free(leida); seguidos para que saltara algo y no salta...
Creo que también debería dejar de usar memoria dinamica que esta al pedo y usar estatica (como dijo Virus).


Cita:A una cosa más, si tenes una cantidad definida de valores, podes usar enums(http://stackoverflow.com/questions/11025...-enum-in-c) en vez de strings

No entendi, en que lugar decís que podría reemplazar strings por enums?


Muchísimas gracias por la ayuda, la verdad me sirve muchísimo!
(Este mensaje fue modificado por última vez en: 21-03-2014 01:50 por agusbrand.)
21-03-2014 01:42
Envíale un email Encuentra todos sus mensajes Agregar agradecimiento Cita este mensaje en tu respuesta
dezine18 Sin conexión
Militante
Sin estado :(
***

Ing. en Sistemas
Facultad Regional Buenos Aires

Mensajes: 52
Agradecimientos dados: 1
Agradecimientos: 44 en 21 posts
Registro en: Oct 2008
Mensaje: #5
RE: Consulta Ej. 2 de la guia operativos
Cita:Claro, entiendo el problema,pero me estoy volviendo loco porque probe en linux(eclipse), y windows y no me salta el problema tener muchos free a la misma cosa. Hasta probe poner tres free(leida); seguidos para que saltara algo y no salta...
Creo que también debería dejar de usar memoria dinamica que esta al pedo y usar estatica (como dijo Virus).

Ah.. yo lo probe desde la consola =P
Si, la del array sirve, a menos que quieran que implementes una lectura que no tenga un tamaño máximo y sea tu tarea identificar como hacerlo para que no hay limite,

Es media inconsiste la interfaz que proponen porque por un lado pareciera que tenes que abrir y operar sobre un archivo abierto, y en otros momentos parece que fuera un archivo sin abrir, pero bueno.. capaz la idea es que te des cuenta que hay que diferenciarlas o capaz la pifiaron XD


Cita:No entendi, en que lugar decís que podría reemplazar strings por enums?

Yo decía en el abrir, en vez de usar strings para indicar el modo podrías usar un enum
21-03-2014 01:58
Encuentra todos sus mensajes Agregar agradecimiento Cita este mensaje en tu respuesta
agusbrand Sin conexión
Profesor del Modulo A
me recibiiiiiiiiiiiiiiiiiiiiii...
*****

Ing. en Sistemas
Facultad Regional Buenos Aires

Mensajes: 233
Agradecimientos dados: 121
Agradecimientos: 60 en 21 posts
Registro en: Dec 2010
Mensaje: #6
RE: Consulta Ej. 2 de la guia operativos
(21-03-2014 01:58)dezine18 escribió:  
Cita:Claro, entiendo el problema,pero me estoy volviendo loco porque probe en linux(eclipse), y windows y no me salta el problema tener muchos free a la misma cosa. Hasta probe poner tres free(leida); seguidos para que saltara algo y no salta...
Creo que también debería dejar de usar memoria dinamica que esta al pedo y usar estatica (como dijo Virus).

Ah.. yo lo probe desde la consola =P
Si, la del array sirve, a menos que quieran que implementes una lectura que no tenga un tamaño máximo y sea tu tarea identificar como hacerlo para que no hay limite,

Es media inconsiste la interfaz que proponen porque por un lado pareciera que tenes que abrir y operar sobre un archivo abierto, y en otros momentos parece que fuera un archivo sin abrir, pero bueno.. capaz la idea es que te des cuenta que hay que diferenciarlas o capaz la pifiaron XD


Cita:No entendi, en que lugar decís que podría reemplazar strings por enums?

Yo decía en el abrir, en vez de usar strings para indicar el modo podrías usar un enum

Sii, tenes razon, ahi queda mucho mejor un enum, no me daba cuenta!
Y el ejercicio es un poco confuso, pero con todo esto aprendi un monton jaja gracias!
21-03-2014 02:05
Envíale un email Encuentra todos sus mensajes Agregar agradecimiento Cita este mensaje en tu respuesta
dezine18 Sin conexión
Militante
Sin estado :(
***

Ing. en Sistemas
Facultad Regional Buenos Aires

Mensajes: 52
Agradecimientos dados: 1
Agradecimientos: 44 en 21 posts
Registro en: Oct 2008
Mensaje: #7
RE: Consulta Ej. 2 de la guia operativos
Ahhh, una boludez más sintactica, si tenes un puntero a función, para evaluarlo no hace falta desreferenciarlo, podes hacer: f(p) en vez de (*f)(p)
21-03-2014 10:59
Encuentra todos sus mensajes Agregar agradecimiento Cita este mensaje en tu respuesta
Buscar en el tema
Enviar respuesta 




Usuario(s) navegando en este tema: 1 invitado(s)