[ Foro de Pascal ]

Guardar cambios en un fichero

16-Jan-2013 17:44
Antonio Rodrigues
21 Respuestas

Lo que pasa es lo siguiente. Yo tengo mi programa. En el programa yo empiezo una cesta de compra nueva. Añado todos los productos que quiero y luego guardo la cesta en un fichero de tipo que es el siguiente:

type
   producto = record
            nombre: string;
            num_unidades: integer;
            precio_unidad: real;
            en_cesta: boolean;
   end;

   cesta=array[0..tamxcesta] of producto;

   Tfichero=file of producto;

Como podéis ver, tengo un registro llamado producto que es donde se guardan los datos de un producto. Luego tengo una tabla llama cesta que es del tipo producto (el registro) que es donde se guardan los datos de varios producto (bueno se guardan los datos de tamxcesta producto donde tamxcesta es un constante que en este caso es igual a 3). Por cierto, en la tabla podéis ver que va desde o hasta tamxcesta [0..tamxcesta], pero el 0 olvidaros de él, porque es para una cosa especial y no vamos a trabajar con el, es decir, vamos hacer como si la tabla fuera de 1 [1..tamxcesta].
Luego podéis ver que tengo un fichero llamado Tfichero que es del tipo producto (el registro). En ese fichero es donde guardo las varias tablas que tengo.

Este es el procedimiento que utilizo para guardar una cesta que acaba de ser creada:

procedure guarda_cesta(var mi_cesta: cesta; var Nfichero: string);  
         var
            fichero: Tfichero;
            i: integer;

         begin
              writeln('Para guardar una cesta nueva solo tienes que introducir su nombre a continuacion:');
              writeln;
              write('Nombre: ');
              readln(Nfichero);

              assign(fichero, Nfichero);
              rewrite(fichero);

              write(fichero, mi_cesta[0]);

              for i:=1 to tamxcesta do
                  if (mi_cesta[i].en_cesta=true) then
                     write(fichero, mi_cesta[i]);

              close(fichero);

              fichero_guardar_pedidos(Nfichero);

              writeln;
              writeln('Su cesta de la compra se ha guardado con exito.');
              readln;
              clrscr;
         end;

Supongo que hasta ahora lo vais entendiendo, así que sigo.

Después de haber creado unas cuantas cestas (yo he creado 3 cestas. La 1º cesta se llama micesta.dat, la 2º cesta se llama micesta2.dat y la 3º cesta se llama micesta3.dat).

Ahora que ya tengo esas 3 cestas creadas yo si quiero puedo abrir las cestas y puedo añadir productos nuevos (claro si aun no esta llena), puedo eliminar algún producto de la cesta y puedo modificar un producto de la cesta.
Al principio tenia un problema que era que cuando yo abría una cesta y luego cambiaba algo (cuando digo cambiaba algo me refiere a si añado un producto nuevo o elimino uno ya existente o modifico uno ya existente) esos cambios no se guardaban en el fichero y al no quedar guardados en el fichero siempre que yo salia del programa, volvía a entrar la cesta no tenia los nuevos cambios.

Para solucionar este problema he hecho un procedimiento que es el siguiente:

procedure guarda_cambios(var Nfichero: string; var mi_cesta: cesta);
         var
            fichero: Tfichero;

         begin
              assign(fichero, Nfichero);
              reset(fichero);

              write(fichero, mi_cesta[0]);

              for i := 1 to tamxcesta do
                  if (mi_cesta[i].en_cesta = true) then
                     write(fichero, mi_cesta[i]);

              close(fichero);
         end;

Con este procedimiento, siempre que abro una cesta y añado o modifico un producto de la cesta los cambios también se guardan en el fichero y así siempre que salgo del programa y vuelvo a entrar los cambios están ahí guardados.

Os habéis fijado que en el parágrafo anterior solo he dicho añadir o modificar un producto. Es verdad, porque para eliminar un producto tengo un problema y aquí es donde necesito ayuda.

Como he dicho antes con este ultimo procedimiento siempre que añado un producto nuevo o modifico uno ya existente los cambios se guardan en el fichero, pero cuando elimino un producto los cambios no se guardan. Siempre que elimino un producto la cesta sigue igual y los cambios no se guardan.

Necesito ayuda porque no se que hacer para que cuando elimino un producto los cambios se guarden.
Me pueden ayudar ??


17-Jan-2013 02:39
Luis Torres (+12)

No veo que el último procedimiento que escribiste haga lo que dices. No has abierto un archivo para la escritura y así poder guardar los cambios en él, lo abriste unicamente para la lectura.
Otra cosa es que no estoy de acuerdo con que utilices ciclos for desde 1 hasta tamxcesta, porque si en la cesta sólo tienes dos productos, entonces copiaría basura en el archivo que estás creando. De todas maneras vamos a ver lo que opina el profesor Nacho Cabanes.
Saludos.


17-Jan-2013 03:07
Antonio Rodrigues

Yo no se otra forma de hacerlo. Esta es la unica forma que se.
Pero de la forma que lo he hecho me sirve para cuando añado o modifico un producto porque me guarda todos los datos bien y no me da problemas. Pero cuando es para eliminar un producto no me funciona y aqui es donde necesito ayuda.


17-Jan-2013 16:53
Luis Torres (+12)

Bueno, el elemento de índice cero (0) guarda el número de productos de la cesta, se puede utilizar el campo que guarda esa cantidad.
El código que escribiste no guarda ningún cambio en la cesta, no entiendo cuando dices que sí lo guarda.
Saludos.


17-Jan-2013 16:57
Antonio Rodrigues

El indice (0) de la cesta como dije antes no se puede utilizar porque esta para otra cosa no es para guardar el numero de productos. Es para algo especial que aqui no nos importa.

Como dije antes, yo utilizo este procedimiento para guardar los cambios:

procedure guarda_cambios(var Nfichero: string; var mi_cesta: cesta);
         var
           fichero: Tfichero;

         begin
             assign(fichero, Nfichero);
             reset(fichero);

             write(fichero, mi_cesta[0]);

             for i := 1 to tamxcesta do
                 if (mi_cesta[i].en_cesta = true) then
                     write(fichero, mi_cesta[i]);

             close(fichero);
         end;

Ya se que en realidad no se guardan los cambios, en realidad lo que hace es volver a escribir la cesta en el fichero, pero al escribir se escriben tambien los cambios. Esto me funciona para cuando tengo que añadir o modificar algun producto. Puede que no sea la mejor forma de hacerlo pero es la unica forma que se de hacerlo.

Pero cuando es para eliminar producto esta forma no sirve.
Aqui es donde necesito ayuda.


17-Jan-2013 18:09
Luis Torres (+12)

Mira una cosa:
En

 
  assign(fichero, Nfichero);
  reset(fichero);
 


abres el archivo para la lectura, o sea que no lo puedes utilizar para la escritura en:

 
   write(fichero, mi_cesta[0]);
 
   for i := 1 to tamxcesta do
    if(mi_cesta[i].en_cesta = true) then
     write(fichero, mi_cesta[i]);
 


Si me puedes pasar el programa completo, por favor. Si quieres me lo envías a mi dirección de correo electrónico.


17-Jan-2013 22:50
Luis Torres (+12)

He probado tu código y sí, efectivamente, guarda los cambios en el archivo. Lo que sucede es que no debería hacerlo, porque si un archivo se abre para la lectura sólo debe permitirse manipularse para tal fin. Esto ya escapa a mis conocimientos, así que sería una buena opción que el prof. Nacho Cabanes nos de una ayuda sobre este tema.
Lo que sí te puedo decir es que puedes aplicar la técnica para eliminar un registro en un archivo que está en el otro post; aquel en el que se usaron los comandos "rename" y "erase". Así sí eliminará "el producto" de la cesta en el archivo.
Saludos.


18-Jan-2013 02:20
Antonio Rodrigues

Te voy a enviar el programa completo para que lo veas a ver si saber como solucionar el problema. Y yo intentare hacer eso del rename y erase a ver si consigo hacerlo.


18-Jan-2013 02:40
Antonio Rodrigues

Oye, ya he encontrado la forma de hacer que se guarden los cambios cuando eliminas un producto.

procedure eliminar(var Nfichero: string; var mi_cesta: cesta);
         var
            fichero, fichero2: Tfichero;

         begin
              assign(fichero, Nfichero);
              assign(fichero2, 'bAsUrA.dat');
              reset(fichero);
              rewrite(fichero2);

              read(fichero, mi_cesta[0]);

              write(fichero2, mi_cesta[0]);

              for i:=1 to tamxcesta do
                  if (mi_cesta[i].en_cesta=true) then
                     write(fichero2, mi_cesta[i]);

              close(fichero);
              erase(fichero);

              close(fichero2);
              rename(fichero2, Nfichero);
         end;

Este es el procedimiento que utilizo. Luis, te he enviado el programa, cuando lo abras, copia este procedimiento y añadelo al programa. Luego tienes que añadir esto:

eliminar(Nfichero, mi_cesta);

Al final del procedimiento "eliminar_prod();" para que funcione.

Ahora voy a probar este procedimiento con añadir producto y modificar producto, ya que se queda mejor que el otro.


18-Jan-2013 02:45
Antonio Rodrigues

Acabo de probarlo para añadir un producto, para eliminar un producto y para modificar un producto y funciona al 100%.


18-Jan-2013 15:32
Luis Torres (+12)

Sí, yo también lo probé y funciona bien. Te felicito por la manera de programar, lo haces de una forma muy clara y, aprendes rápido las cosas. De seguro serás un muy buen programador.
Saludos.


18-Jan-2013 20:23
Antonio Rodrigues

Gracias por el comentario Luis. Ahora que ya tengo mis problemas resueltos hasta esta parte del programa, me voy a poner a trabajar en el para terminar los 2 últimos ejercicios y terminar el programa por completo.


22-Jan-2013 18:19
Luis Torres (+12)

Espero que cuando termines el programa por completo me lo envíes a mi dirección de correo electrónico.
Saludos.


22-Jan-2013 18:39
Antonio Rodrigues

Claro. Te lo voy a enviar.


23-Jan-2013 23:44
oscar gomez

Hola Antonio.
gracias de antemano por tu programa es un muy buen ejercicio de aplicacion para el tema de archivos, sin embargo noté algo que no va muy bien en el programa, y es respecto a lo siguiente, imaginate que tengo dos cestas creadas y las abro a traves de la opcion 2 del menu principal del programa, en este momento tendriamos dos cestas abiertas al mismo tiempo, hasta ahi ok, pero imaginate ahora que deseo modificar un producto de una de esas cestas, atraves de la opcion 7 del menu principal, fijate que el programa falla aqui por que si te das cuenta lo permite hacer, es decir nos permite la modificacion pero para la ultima cesta abierta( en otras palabras la cesta actual), no dando la opcion de poder escoger la cesta a la que deseo modificar un producto, como ves se pierde la esencia de tener o permitir tener mas de una cesta abierta al mismo tiempo, asi que se podria mejorar esta parte que te menciono.
Tambien podria indicarte que en los procedimientos al no pasarle parametros no es necesario los parentesis vacios despues del nombre de los mismos,por lo menos para turbo pascal, no se si sea asi para free pascal.
Espero que hayas podido resolver los dos ejercicios que te envie,sino podemos mirarlo bien sea por el foro o como lo desees.
Espero pronto ponernos en marcha como lo habiamos planificado para inciarnos con el tema grafico que es la parte interesante de pascal pues como sabes pascal ya esta algo obsoleto, sin embargo es buen lenguaje para aprender la filosofia estructurada ya sabes procedimental y demas,la parte grafica es otra cosa en este lenguaje al ser un entorno bastante practico para proximos lenguajes como porejemplo realizar videojuegos en moviles a traves de androide entre otros, pero eso lo podemos madurar cuando termines tu examen y yo con el mio de listas doble enlazadas.un abrazo.


24-Jan-2013 01:33
Antonio Rodrigues

Mira Oscar, el programa no esta hecho para tener 2 cestas abiertas el mismo tiempo. Solo puedes tener 1 cesta abierta de cada ves. Si quieres hacer algo en una cesta la abres y haces lo que tengas que hacer, pero si quieres hacer algo en otra cesta, primero la debes abrir. He dejado las indicaciones en el propio programa diciendo eso.

Por ejemplo, tu hablas sobre la opcion 7 que es para modificar un producto. Antes de modificar el producto pone que solo puedes modificar el producto de la cesta abierta actualmente. Y tambien pone que si quieres modificar el producto de otra cesta primero la debes abrir.

Eso es lo primero.

Cuanto a los procedimiento con los parentesis, ya se que no hace falta que tengan parentesis si no tienen variables, pero yo prefiero poner los parentesis porque para me resulta mas facil de esa forma. Para mi es mejor con los parentesis porque asi no me equivoco.

Y por ultimo, eso de la parte grafica. Te lo he dicho antes ya 2 veces pero te lo vuelvo a repetir. Ahora mismo estoy estudiando para el examen que tengo dentro de 1 semana y 4 o 5 dias. Hasta que no haga el examen no voy a empezar nada nuevo. Y, cuando haga el examen voy a seguir estudiando pero por mi cuenta y solo, porque voy a empezar a trabajar y no voy a tener casi tiempo para estudiar.


24-Jan-2013 12:13
oscar gomez

Hola Antonio,
Cuando me enviaste el programa, me dijiste que lo mirara y que si veia algo te lo contara y eso fue lo que hice pero parece que no recibes consejos, esa respuesta que me das de que ya lo sabias resulta un tanto prepotente de tu parte, solo lo comente, no como una critica a tu solucion sino como una observacion desde mi punto de vista, pues no olvides que muchas veces la idea no es hacer programas para uno mismo sino para que los demas puedan entender de lo contrario estamos siendo egoistas y egocentricos, perdiendo asi la esencia del concepto de programador y si se programa para uno mismo pues lo mejor es demostrar que no se necesita ayuda de nadie y no pedirla...Eso por una parte, la otra es que a pesar que en los mensajes que haces a manera de informacion para el usuario, insisto no me parecen muy acordes con lo que permites en tu programa pues para que entonces permite el programa abrir dos y mas cestas a la vez, si a la final solo te permite trabajar con una sola cesta, a eso es  a lo que me referia pero claro olvidaba que para ti tu programa es la panacea..., los mensajes da igual si la realidad de un programa se contradice...
En cuanto a lo de la parte grafica fuiste tu quien me dijo que te parecia buena idea y que despues de tu examen lo mirabas, a mi me da igual que estudies o no y mas si lo haces solo a acompañado pero de seguro que por aqui te vere pidiendo ayuda,es tu problema,si te lo plantee fue por ayudarte con documentacion de mi universidad no por que lo necesite yo.creo que te falta es humildad para aprender...


24-Jan-2013 14:46
Antonio Rodrigues

Pues aqui tenemos un problema, porque has intrepretado mal mi mensaje anterior.

A lo mejor fue mi forma de escribir no se.

Bueno, voy a esclarecer aqui las cosas. Voy a ir copiando los que has dicho y lo dejo entre comillas y lo explico.

"Cuando me enviaste el programa, me dijiste que lo mirara y que si veia algo te lo contara y eso fue lo que hice"

Esto es verdad y fue lo que has hecho y te lo agradezco.

"pero parece que no recibes consejos, esa respuesta que me das de que ya lo sabias resulta un tanto prepotente de tu parte, solo lo comente, no como una critica a tu solucion sino como una observacion desde mi punto de vista, pues no olvides que muchas veces la idea no es hacer programas para uno mismo sino para que los demas puedan entender de lo contrario estamos siendo egoistas y egocentricos, perdiendo asi la esencia del concepto de programador y si se programa para uno mismo pues lo mejor es demostrar que no se necesita ayuda de nadie y no pedirla"

Pero aqui ya te has pasado 3 pueblos. Vamos a ver esto poco a poco.

"pero parece que no recibes consejos"

Me gustaria saber porque dices esto ?? Que yo sepa nunca he dicho  nada de no recibir consejos y mi mensaje anterior tampoco pone nada sobre eso ni directa ni indirectamente.

"esa respuesta que me das de que ya lo sabias resulta un tanto prepotente de tu parte"

Porque resulta prepotente ?? Lo unico que he hecho fue decirte que en el programa solo se puede abrir 1 cesta de cada ves y que el propio programa tiene las indicaciones diciendo eso. No te he dicho nada sobre que ya lo sabia o que no sabia.

"solo lo comente, no como una critica a tu solucion sino como una observacion desde mi punto de vista"

Y te agradezco que lo comentes porque asi me has dado la "idea" de poner para que se pueda abrir mas de 1 cesta al mismo tiempo.

"pues no olvides que muchas veces la idea no es hacer programas para uno mismo sino para que los demas puedan entender de lo contrario estamos siendo egoistas y egocentricos, perdiendo asi la esencia del concepto de programador y si se programa para uno mismo pues lo mejor es demostrar que no se necesita ayuda de nadie y no pedirla"

Lo siento pero no se porque dices esto. Mi programa esta hecho no para mi, sino para los demas. Ya se que puede no ser muy bueno y esta el problema ese de poder abrir solo 1 cesta, pero hombre dame un respiro. Aun soy un novato y esto no es facil para mi. Yo lo he hecho asi de esta forma para luego ir mejorandolo. Por eso te lo he enviado a ti y a otras personas para que lo vean y me digan sus opiniones y me comenten cosas que se pueda poner en el programa. Y antes de que se me olvide, en la respuesta enterior se me olvido añadir una cosa muy importante. Si miras la respuesta hay un sitio que dice

"Eso es lo primero".

Antes de esto yo tenia que haber puesto lo siguiente:

"Gracias por tu comentario. Cuando tenga tiempo añadire esa mejora a tu programa."

El problema es que se me olvido.

".Eso por una parte, la otra es que a pesar que en los mensajes que haces a manera de informacion para el usuario, insisto no me parecen muy acordes con lo que permites en tu programa pues para que entonces permite el programa abrir dos y mas cestas a la vez, si a la final solo te permite trabajar con una sola cesta, a eso es  a lo que me referia pero claro olvidaba que para ti tu programa es la panacea..., los mensajes da igual si la realidad de un programa se contradice..."

Aqui hay una cosa que te equicovas. Dices que los mensajes contradicen el programa pero es mentira. Los mensajes ponen que solo se puede abrir 1 cesta a la ves (con otras palabras claro) y eso es lo que se puede hacer.

"En cuanto a lo de la parte grafica fuiste tu quien me dijo que te parecia buena idea y que despues de tu examen lo mirabas, a mi me da igual que estudies o no y mas si lo haces solo a acompañado pero de seguro que por aqui te vere pidiendo ayuda,es tu problema,si te lo plantee fue por ayudarte con documentacion de mi universidad no por que lo necesite yo.creo que te falta es humildad para aprender..."

Cuanto a esto te dije que me guste la idea y es verdad, pero el problema es que no voy a tener tiempo. Por eso te dije que voy a seguir estudiando por mi cuenta, porque puede que no tenga tiempo ni para seguir y no queria decirte que si que podemos estudiar juntos y luego tener que decir que no puedo. Por cierto cuando dije eso de solo me referia que por mi cuenta, es decir, que sin tener compromisos con nadie ni con nada. Y claro, si tengo alguna duda o algo vendre a este foro a otro a pedir ayuda, pero eso si tengo tiempo.


24-Jan-2013 15:22
oscar gomez

Hola, con la disculpa de mi parte para el profesor Nacho Cabanes que nos da este espacio para aprender y no discutir, sin embargo tu respuesta fue publica con alucion directa a mi , asi que debia responder como lo hago ahora tambien por que estas manipulando tus respuestas, pues si que mencionas que ya sabias que en los procedimientos no deberian ir los parentesis y lo unico que intente fue aconsejarte que no hacian falta y tu respuesta textual fue "Cuanto a los procedimiento con los parentesis, ya se que no hace falta que tengan parentesis si no tienen variables, pero yo prefiero poner los parentesis porque para me resulta mas facil de esa forma. Para mi es mejor con los parentesis porque asi no me equivoco."
De ahi mi comentario de prepotente,no ocultes lo que es evidente...
En fin tio que no vale la pena utilizar este espacio que Nacho nos permite para perder el tiempo en tonterias, pero si que tengas y aprendas o intentes aplicar los consejos que te intente dar en el primer mensaje de esta absurda discusion.
En ningun momento te pedi que estudiaramos los dos, solo te di la idea por ayudarte a que tuvieras documentacion pero la desaprovechaste como algun otro por aqui,pero la cuestion es de madurar y el tiempo ayuda a ello asi que de mi parte cierro esta absurda discusion, tu sigue con lo tuyo que a mi me da igual, solo intente poner mi punto de vista a un programa que desde un inicio te comente que era bastante interesante sin jamas criticar tu solucion como lo intentas hacer ver a este grupo del foro,por eso te dije lo de que no sabes recibir consejos,por que en vez de analizar mis indicaciones lo que hiciste fue como defenderte de algo que no tiene pies ni cabeza.


24-Jan-2013 17:00
Antonio Rodrigues

Se cierra el tema. Oscar luego mira el mensaje en tu email.


25-Jan-2013 22:42
oscar gomez

Hola Antonio, me preguntas lo siguiente:
“necesito tu ayuda. En mi programa de la cesta el que te he enviado, estoy trabajando en el y modificando muchas cosas y necesito que me des tu opinion.
Esta ves la puedes dar que no voy a criticar ni nada solo te dare las gracias.
Tu sabes que en el programa hay una opcion (es la opcion 3 del menu principal) que sirve para empezar una cesta de la compra nueva. Cuando le dar a esa opcion te sale otro menu y en ese menu puedes añadir, eliminar productos, etc. Bueno, cuando le das a añadir, pones el nombre la cantidad y el precio y se añade un nuevo producto a la cesta. Pero para añadir un 2º producto tienes que volver a seleccionar la opcion para añdir. Lo que yo quiero saber es si lo dejo asi de esta forma o entonces lo pongo de la siguiente forma:

Cuando le das a añadir productos, tiene que añadir los 3 que es lo maximo de la cesta y luego vuelves al menu ?? ”

te respondo:


Hola tio me alegra la madurez que has tenido en tus disculpas que por supuesto las acepto.
.
respecto a lo que me preguntas, te puedo decir que el hecho que la cesta contenga como maximo tres productos no implica que la cesta deba llenarse con tres productos obligatoriamente una vez escogida la opcion de añadir productos, es decir no es rigurosamente obligatorio añadirsen los tres produtos, puedes añadir uno solo, o dos o los tres, lo que si es que en el programa no debes permitir añadir mas de tres productos por  lo que debes controlarlo y que me imagino no tendra complicacion alguna para ti hacer tal validacion, asi que en este caso tal como lo tienes tu hasta el momento te sugeriria que una vez escogida la opcion de añadir producto(nombre, cantidad y precio) preguntes porejemplo a traves de un repeat si se desea incluir mas productos en la cesta en cuestion, si la respuesta del usuario es true, pues se permitira ingresar los nuevos datos del nuevo producto( sin que hayas salido al menu), si la respuesta es false, en ese caso se sale al menu donde estabas, es lo mas practico que veo yo, sin embargo es mi punto de vista, espero que pueda darte luz con mi respuesta al respecto.
saludos.


26-Jan-2013 00:23
Antonio Rodrigues

Gracias por el consejo Oscar. Antes se me habia ocurrido tambien esa idea, pero luego me he puesto a pensar y no estaba seguro de si era o no un buena idea. Pero veo que si lo es.
Una ves mas gracias por el consejo.
Luego cuando termine de modificar el programa te lo envio para que veas como ha quedado.






(No se puede continuar esta discusión porque tiene más de dos meses de antigüedad. Si tienes dudas parecidas, abre un nuevo hilo.)