[ Foro de Pascal ]

Ficheros

28-Dec-2012 15:19
Antonio Rodrigues
44 Respuestas

Estoy terminando de ver Pascal, pero en la parte de los ficheros tengo un problema.

Bueno, dejo aqui mi problema.

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;

Esto es un registro, una tabla del tipo registro y un fichero del tipo registro que tengo en mi programa. Bueno, lo que tengo que hacer es inicializar la tabla, pidiendo al usuario que rellene todos los campos de la misma (eso esta hecho). Luego, tengo que guardar todos los produtos (los datos que estan en la tabla) en un fichero. Yo lo he hecho de la siguiente forma:

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

         begin
              write('Introduzca el nombre de la cesta: ');
              readln(Nfichero);

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

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

              close(fichero);
              clrscr;
         end;

Lo que me gustaria saber es si esta bien hecho ?? Porque cuando lo utilizo no se guarda bien las cosas (puede ser un error mio).

Luego, Tengo que llevar el fichero donde he guardado los productos a otro procedimiento y en ese procedimiento lo que tengo que hacer es leer los productos que estan en el fichero y guardar esos productos en la tabla del tipo registro, para luego mostrar los productos por pantalla. Lo que he hecho es lo siguiente:

procedure recupera_cesta(var Nfichero: string);
         var
            fichero: Tfichero;
            i: integer;

         begin
              write('Introduzca el nombre de la cesta: ');
              readln(Nfichero);

              i:=0;

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

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

              close(fichero);
              readln;
              clrscr;
         end;

Lo que me gustaria saber es si esta bien o si le falta algo (yo creo que le falta algo, pero no se el que) ??


29-Dec-2012 06:55
Luis Torres (+12)

¿De dónde sacas la variable "tamxcesta"?. Saludos.


29-Dec-2012 14:34
Antonio Rodrigues

Lo variable "tamxcesta" es una constante. Se quedaria asi:

const
    tamxcesta= 3;

Le puedo dar el valor que quiera, pero en este caso le he dado 3 para que no sea un valor muy grande.


29-Dec-2012 23:18
Luis Torres (+12)

El procedimiento guarda cesta está bien hecho, no le veo ningún error. ¿Por qué dices que te guarda bien las cosas?.

¿Podrías colocar el enunciado del problema? y todo el código que has hecho?, puedes adjuntar el archivo con todo el código junto a tu mensaje haciendo click sobre "Archivo adjunto: (opcional".

¿El usuario debe llenar todos los productos en un arreglo?, ¿en total son 4 productos?, ¿cómo queda el campo "en_cesta"?

¿Cada fichero es una compra?, ¿son varios archivos que se deben crear?

Saludos.


30-Dec-2012 01:59
Antonio Rodrigues

Bueno, como tu dijiste, aqui dejo todo el programa.
Y tambien dejare los enunciados.

El programa es un programa hecho con varios ejercicios. Es decir, he estado haciendo varios ejercicios y cada uno de ellos era como una parte mas del programa final. En el programa solo necesito ayuda con el procedimiento guarda_cesta y con el procedimiento recupera_cesta. Todos los demas procedimientos son de ejercicios anteriores que estan hecho y comprobados y funcionan sin problemas.

Para el procedimiento guarda_cesta este es el enunciado:

"Codifique un procedimiento (guarda_cesta) que guarda todos los productos de una cesta de la compra, que se pasa como parámetro, en un fichero cuyo nombre también se pasa como parámetro.

Tenga en cuenta que salvo el producto que ocupa la posición cero (que como ya veremos tiene un significado especial) todos los demás están en la cesta sólo si el campo en_cesta=TRUE, si este campo es FALSE no necesitamos, por tanto, guardar ese producto en el fichero."

Para el procedimiento recupera_cesta este es el enunciado:

"Codifique un procedimiento (recupera_cesta) que lea de un fichero de elementos de tipo producto, cuyo nombre se pasa como parámetro JUNTO CON OTROS QUE CONSIDERE NECESARIO, todos los productos que tenga almacenados y los guarde en una variable del tipo cesta que también se pasa como parámetro. Asegúrese de que no se sobrepasarán los límites de la cesta intentando introducir más de TAMMAXCESTA."

Por ultimo, en el programa que dejo aqui, lo que esta dentro del "BEGIN..END" principal (del modulo principal) es otro ejercicio que viene despues de estos 2 que he dejado antes. Voy a dejar aqui el enunciado por si tienes alguna duda:

"Codifique un módulo principal en el que reutilizando los resultados de cuestiones y actividades anteriores (procedimientos de lectura y escritura de ficheros, presentación, modificación de datos de una cesta…), se muestre al usuario el menú propuesto en la actividad anterior y se ejecuten las acciones pertinentes a cada opción.
Tenga en cuenta que si el usuario elige:
1. Abrir cesta de compra existente: se preguntará al usuario el nombre de la cesta (que será el nombre del fichero que la contiene).
2. Comenzar cesta de compra nueva: se creará una cesta desde cero.
5. Guardar cesta: se pedirá al usuario el nombre del fichero donde guardar la cesta.
6. Pedir cesta: se mostrará la cesta actual.
7. Salir del programa: se terminará la ejecución del programa."

En el enunciado, cuando dice el menu propuesto en la actividad anterior, se refiere al menu que yo he puesto ya en el programa. Dentro del "BEGIN..END" principal (del modulo principal) hay un manu con 7 opciones. Ese es el menu.


30-Dec-2012 03:24
Antonio Rodrigues

Bueno, en mi mensaje anterior iba a dejar el ejercicio, pero no me he dado cuenta que solo se pueden poner hasta 10KB. Asi que aqui dejo mi ejercicio.
He divido mi ejercicio en 2 partes (ejercicio - parte 1 y ejercicio - parte 2). Luego, juntas las 2 partes. solo tienes que copiar todo lo que esta en la parte 2 y pegarlo en la parte 1 debajo del ultimo procedimiento y dejarlo todo como esta.

Aqui dejo la parte 1.


30-Dec-2012 03:24
Antonio Rodrigues

Y aqui dejo la parte 2.


30-Dec-2012 22:45
Luis Torres (+12)

Bueno, no te podré ayudar porque no entiendo bien el problema, no sé cómo se maneja la fulana "cesta", ¿será que cada archivo es una cesta?. Yo manejo bien los archivos, pero si no entiendo el problema no puedo ayudarte. Saludos y espero que otro forista te pueda hechar una mano.


31-Dec-2012 00:09
Antonio Rodrigues

Cuando dices "cesta" a cual te refieres ??  A la cesta del programa, o a la cesta del procedimiento recupera_cesta ??


31-Dec-2012 04:09
Luis Torres (+12)

Me refiero a el significado de "cesta". ¿Es como un carrito de compras?. ¿Cuántos archivos deben haber en el programa?. ¿El o los archivos guardan todos los productos?, ¿cuántos productos son?. Son muchas cosas que no tengo en claro, y son de la parte de "Análisis del Problema", debe tener claro eso para poder avanzar. En archivos, yo estoy bien, los sé manejar. Saludos.


31-Dec-2012 04:47
Antonio Rodrigues

Mira esto es lo siguiente. Todos los procedimientos que estan antes de cesta_de_compra son procedimiento para utilizar en el propio procedimiento cesta_de_compra. Hasta el procedimiento cesta_de_compra es una actividad y lo que viene despues es otra.
Hasta ese procedimiento lo unico que debe hacer el programa es trabajar con 1 sola cesta de la compra que puede tener hasta un X numero de productos (esto esta limitado por tamxcesta). Lo que el usuario puede hacer aqui es añadir productos a la cesta de la compra (hasta un maximo de tamxcesta), eliminar algun producto de la cesta, modificar algun producto de la cesta, ver todos los productos que estan en la cesta y ver cuantos productos estan en la cesta.

Los procedimientos que vienen despues (guarda_cesta y recupera_cesta) y el menu del BEGIN..END principal (del modulo principal) son de otra actividad. En esta actividad lo que se tiene que hacer es trabajar con mas de 1 cesta de la compra. Es decir, al principio no tenemos ninguna cesta ni ningun producto,entonces lo que hacemos es elejir la opcion de empezar una cesta nueva (opcion 2). Ahi ponemos todos los productos etc. Luego, podemos (opcion 3) añadir un producto a la cesta pero claro si aun no esta llena. Tambien podemos eliminar un producto de la cesta. Tambien podemos pedir cesta, es decir, ver la cesta (sus productos). Estas 3 opciones depende. Si tenemos solo 1 cesta, pues se aplican a esa cesta que tenemos. Pero si tenemos mas de 1 cesta las opciones se aplican a la ultima cesta con la que hemos trabajado.
Por ultimo tenemos 2 opciones mas. La opcion 5 que sirve para cuando allamos creado una cesta (opcion 2) la podamos guarda en un fichero con el nombre que queramos. Asi de esta forma podemos trabajar con mas de 1 cesta. Y luego la opcion 1 que es para que podamos ver las cestas que tenemos (sus productos). Esta opcion es mas para cuando tenemos mas de una cesta. Solo ponemos el nombre de la cesta y vemos sus productos.

Te ha quedado todo claro o aun tienes alguna duda mas ?


01-Jan-2013 03:00
Luis Torres (+12)

En primer lugar te felicito por lo claro del código y la organización que tienes al programar.
Cuando tratas de leer una cesta (archivo guardado) no leerá los productos almacenados en el archivo. El error está en el procedimiento recupera_cesta. Lo implementaste mal. Abres bien el archivo, pero estás preguntándote si el campo "en_cesta" del producto es "true" sin antes haber leído el primer producto. Así que no leerá nada. Otra cosa que encontré es que usas el ciclo for, pero no sabes cuántos elementos hay en el archivo, pueden haber 1, 2 y, si usas el for tal y como está, tratará de leer 3 productos. Yo en su lugar utilicé un while. Aquí te dejo el procedimiento tal y como yo lo hice:

 
procedure recupera_cesta(var Nfichero: string); (* PROCEDIMIENTO MODIFICADO DEL CODIGO ORIGINAL *)
          var
             fichero: Tfichero;
             i: integer;
			 UnProducto: producto;
 
          begin
               write('Introduzca el nombre de la cesta: ');
               readln(Nfichero);
 
               i:=0;
 
               assign(fichero, Nfichero);
               reset(fichero);
 
			   while not Eof(fichero) do
			    begin
			      read(fichero, UnProducto);
                  i:= i+1;
                  if (UnProducto.en_cesta=true) then
				    mi_cesta[i]:= UnProducto;						   
                end;
 
               close(fichero);
               readln;
               clrscr;
          end;
 
 
 

01-Jan-2013 03:52
Antonio Rodrigues

Es que, yo empece a ver los ficheros hace muy poco tiempo y aun no estoy muy acostumbrado a trabajar con ellos, y ademas hacer lo que me pide en el procedimiento recupera_cesta era difícil para mi, pero por lo menos lo he intentado.

Y ahora, te doy la gracias por la paciencia que has tenido conmigo y por la ayuda que me has dado.

Muchas gracias.


01-Jan-2013 04:21
Antonio Rodrigues

He estado probando las cosas nuevas y solo necesito saber una cosa mas. En el procedimiento recupera_cesta, lo que hago es poner los productos que estan guardados en el fichero de nuevo en la cesta. Pero luego, lo que tengo que hacer es mostrar esos productos por pantalla.
Es decir, tengo que hacer otro procedimiento (por ejemplo lo llamaremos ver_productos)  donde dentro de el llamo al procedimiento recupera_cesta para poner los productos en la cesta, pero luego en el procedimiento ver_productos es donde esta el write para poder mostrar en pantalla los productos.
El problema es que es la primera ves que hago esto con ficheros y no se como hacerlo. He intentado hacerlo pero no me sale.
Me puedes dar una ayuda ?


01-Jan-2013 05:23
Luis Torres (+12)

Con el cambio que le hice al procedimiento recupera_cesta ya muestra los productos almacenados en un fichero. Por cierto en en procedimiento cesta_de_compras debe colocar el "var" antes del parametro.
Hay algunas cosas que no comprendo el por qué las haces, por ejemplo inicializar el arreglo desde cero, es mejor hacerlo desde uno, porque desde cero no lo usas en ninguna parte. Otra cosa es el uso del campo en_cesta. No te sirve de nada, porque si metes en un archivo un producto es porque lo tienes en la cesta.
Los menús tampoco son los más apropiados. Añadir Producto no debería estar en el menú principal
Saludos.


01-Jan-2013 11:14
Luis Torres (+12)

El procedimiento mostrar_cesta muestra los elementos. Ya lo tienes hecho. Saludos.


01-Jan-2013 14:34
Antonio Rodrigues

Empiezo la cesta desde 0 porque hasta ahora no he utilizado el 0, pero lo voy a utilizar despues para una cosa especial. Y el campo en_cesta sirve para por ejemplo si quiero eliminar un productos de la cesta.
Y otra cosa, tu has dicho que con lo que hiciste en el procedimiento recupera_cesta ya se puede ver los productos, pero yo no puedo verlos y no se porque.


01-Jan-2013 19:08
Luis Torres (+12)

Para poder utilizar recupera_cesta (opción 1 del Menu Principal), debes tener un archivo con una cesta en el disco duro, ¿no?.
Para guardar una cesta (archivo) en el disco duro debes antes haber agregado algún(os) productos a la cesta con la opción 3 del Menú Principal. Una vez que hayas metido los productos que desees debes guardar el archivo (o cesta) con la opción 5 (Guardar Cesta), se te pedirá el nombre, yo coloqué cesta1.dat. Ahora te puedes salir del programa con la opción 7.
Vuelve a entrar al programa y elige la opción 1 (Abrir cesta de compra existente), colocas cesta1.dat y das Enter dos veces. Eso te lleva al Menú Principal nuevamente, allí eliges la opción 5 (Pedir cesta) y te mostrará los productos que están en ese archivo. A mí me funciona bien con la modificación que le hice al procedimiento recupera_cesta. Ese procedimiento debes sustituir el que tenía previamente en tu programa, de esa forma sí funciona, no con el que tenías antes.
Saludos.


01-Jan-2013 19:28
Antonio Rodrigues

Hm, ok entiendo. Pero tengo unas preguntas que hacer.
1º Al guardar la cesta con la opcion 5, tu has dicho de guardar con el nombre de cesta1.dat. En el nombre has puesto el .dat, pero hace falta poner siempre eso de .algo (donde algo puede ser dat o otra cosa cualquiera) o eso no hace falta poner ???

2º Entonces, la opcion 2 (comenzar cesta de compra nueva) para que la utilizo y como ?

3º Has dicho que despues de guardar una cesta tengo que salir del programa y luego volver a entrar. Pero hace falta hacer siempre eso, o simplemente puedo utilizar la ocpion 1 sin salir del programa ??


01-Jan-2013 22:07
Luis Torres (+12)

1.- Pues yo estoy acostumbrado a ver que cada archivo tiene un nombre un punto y una extensión (dat, txt, jpg, gif, etc.), así que lo más lógico es seguir esas normas. Si se puede guardar sin extensión no lo sé, habrá que hacer la prueba, pero guardarlo tal como te lo indiqué funciona bien.
2.- Eso mismo me pregunto yo, creo que el diseño de los menús está mal hecho. Yo los modificaría dejando en el menú principal sólo las opciones de Crear nueva cesta, Abrir una cesta ya existente, Mostrar una cesta ya existente y Salir.
3.- Lo que sucede es que en el arreglo siempre queda los productos que acabas de introducir, hay un procedimiento que inicializa el arreglo, pero no lo utilizas siempre. Debes utilizarlo para limpiar el arreglo y para que al abrir una cesta, ésta se cargue correctamente en el arreglo.


02-Jan-2013 03:53
Antonio Rodrigues

Bueno mira, voy a dejar las funciones de los menús a ver si me puedes ayudar.

Opción 1 (Abrir cesta de compra existente): esta opción lo que tiene que hacer es, primero preguntar al usuario el nombre de la cesta (la cesta que hemos guardado en un fichero) y luego, mostrar los productos de dicha cesta.

Opción 2 (Comenzar cesta de compra nueva): en esta opción lo que hacemos es comenzar una cesta de la compra desde 0. Es decir, en esta opción utilizamos el menú del procedimiento cesta_de_compra para empezar una cesta nueva (añadiendo sus productos, eliminando los que no queremos, modificando los que ya están, etc.)

Opción 3 (Añadir producto a la cesta): esta opción no es para empezar una cesta nueva, sino mas bien para modificar una ya existente. Esta opción, es para añadir un producto a una cesta de la compra ya existente, pero que aun no esta llena (o sea que el numero de sus productos es menor de tamxcesta). Con esta opción, el producto nuevo se añadirá a la cesta que estamos utilizando en ese momento.

Opción 4 (Eliminar producto de la cesta): esta opción es tiene la misma función que la opción 3, solo que en ves de añadir un producto lo que hace es eliminar el producto.

Opción 5 (Guardar cesta): en esta opción, primero se pregunta al usuario en nombre de la cesta para poder guardarla en un fichero. Luego, lo que hace es guarda los productos de una cesta en un fichero con el nombre que le hayamos dado. Esta opción para guarda los productos en un fichero esta hecha para ser utiliza junto con la opción 2 después de haber empezado una cesta nueva. Resumiendo, después de haber utilizado la opción 2 para empezar una cesta nueva desde 0, luego se utiliza la opción 5 para guardar esa cesta en un fichero.

Opción 6 (Pedir cesta): esta opción es casi igual a la opción 1. Esta opción sirve para ver los productos de una cesta de la compra. Pero a diferencia de la opción 1 donde podemos ver los productos de todas las cesta con poner su nombre, en esta opción solo podemos ver los productos de la cesta que estamos utilizando en ese momento.

Opción 7 (Salir del programa): para salir del programa.

Lo que quiero saber es si se puede hacer el programa de esta forma ??

Por cierto, cuando voy a guardar una cesta que tipo se debe utilizar, .dat, .txt , etc. ???


02-Jan-2013 04:06
Luis Torres (+12)

Yo lo que veo muy extraño es que puedas utilizar la opción 3 (Añadir un producto a la cesta) sin haberla creado primero. Me parece más lógico que estuviera dentro de la opción comenzar cesta de compra nueva y dentro de la opción 1; al menos no debería permitir que introduzcas ningún producto si no se ha iniciado una nueva cesta o abierto una ya existente.
Deberías guardar el archivo con la extensión .dat, porque es un archivo de datos, no es un archivo de texto(.txt).
Saludos.


02-Jan-2013 16:27
Antonio Rodrigues

Eso que has dicho que es extraño que la opcion 3 yo tambien lo veo extraño, pero es asi que me pide el ejercicio que lo haga.

Una pregunta, tu has visto como tengo el programa. Si elijes la opcion 2 te lleva al otro menu donde puedes empezar una cesta nueva desde 0. Lo que quiero saber es si yo elijo la opcion 2, me voy al otro menu y empiezo una cesta nueva desde 0, añadiendo productos, o eliminando o modificando. Lo que quiero saber es si despues de haber hecho los cambios que quiero en los productos de la cesta nueva que he empezado, le doy a la opcion f y me vuelvo al menu anterior, y lo que quiero saber es si cuando vuelvo al menu anterior la cesta sigue existiendo, es decir, si sigue ahi, que no se alla borrado o algo y si la puedo guardar en un fichero ??


02-Jan-2013 21:35
Luis Torres (+12)

Sí, después de presionar f, los productos permanecen en la cesta y los puedes guardar en un fichero desde el menú principal.
El problema que yo veo es que cuando ya has trabajado con la opción 3 del menú principal y ya tienes productos en la cesta y, luego eliges la opción 2 para crear una cesta nueva, los productos que elegiste previamente siguen existiendo para la cesta nueva, porque no INICIALIZASTES LA CESTA NUEVA en el procedimiento correspondiente. Si vas a comenzar una cesta nueva, lo común sería que no existiera ningún producto en ella. Así que debería inicializar la cesta cuando el usuario elija la opción 2 del Menú Principal. El procedimiento para hacer eso es inicializa_cesta.
Si te lo mandaron hacer así, pues ni modo, déjalo así, pero no me parece la mejor manera de hacer los menús.
Saludos.


02-Jan-2013 22:24
Antonio Rodrigues

Lo que yo no entiendo es que cuando le doy a la opcion 2 para empezar una cesta nueva, despues añado los productos y de seguida le doy a la opcion f para volver al menu principal y le doy a la opcion 5 para guardar la cesta, pero los productos no estan.


03-Jan-2013 04:39
Luis Torres (+12)

¿Sustituiste el procedimiento que elaboré arriba por el que estaba antes en tu programa?.
Yo acabo de realizar la operación y sí la guardó.
Lo primero que hice, cuando entré, fue elegir la opción de Comenzar Cesta de Compra Nueva (opción 2 del Menú Principal). Luego, introduje dos productos con la opción Añadir Producto a la Cesta (opción 1 del menú secundario). Una vez que introduje dos productos escogí la opción Salir de la Cesta (opción f). Luego, escogí la opción Pedir Cesta (6), MOSTRO LOS DOS PRODUCTOS, finalmente escogí la opción Guardar Cesta (5), la guardé con el nombre de cesta7.dat, luego me salí con Salir del Programa (7). Volví a entrar, escogí 1, metí cesta7.dat, luego seleccioné Pedir Cesta (6) y mostró los dos productos tales como los introduje.
Saludos.


03-Jan-2013 15:10
Antonio Rodrigues

Eso es lo que no entiendo. Yo he sustituido el procedimiento como tu lo has hecho. He hecho todo como tu has dicho todos los pasos, pero no funciona. Le doy a la opcion 2 para empezar una cesta nueva. Luego le doy a la opcion a para añadir productos. De seguida vuelvo al menu principal con la opcion f. Despues le doy a la opcion 6 para ver los productos de la cesta, pero no hay ningun producto.


03-Jan-2013 16:58
Nacho Cabanes (+30)

Me entrometo un momento en vuestra conversación: cuando pasan "cosas raras" con datos que desaparecen, la solución más sencilla suele ser ir mostrando los valores de las variables, para ver dónde se están "perdiendo". A la salida de cada procedimiento (y a veces incluso en puntos intermedios), incluye algún WriteLn, que te muestre en pantalla (o que vuelque a fichero) los valores de los datos que compartes, como el tamaño de la cesta (tamxcesta) o el último número de elemento usado, y también como alguno de los datos del array (típicamente el nombre, pero también puede ser el campo "en_cesta" o algún otro que sea el que pueda estar causando problemas).

Según el entorno de desarrollo que uses, debería existir un "depurador", que te permita ver los valores de las variables sin necesidad de esos "WriteLn", pero a veces es más cómodo mandar todo a pantalla o incluso a un fichero de texto para poder analizarlo después con más tranquilidad.

Aun así, puedes poner el fuente completo para ver si descubrimos el fallo (mejor copia y pega en el texto de un mensaje, en vez de adjuntar: será más fácil de leer para todos).


03-Jan-2013 18:40
Antonio Rodrigues

Muy bien. Aqui esta mi programa:

program Cesta_de_la_compra;

uses crt;

const
    tamxcesta=3;

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;

var
  mi_producto: producto;
  mi_cesta: cesta;
  nombre_producto, Nfichero: string;
  exito, exito2: boolean;
  posicion, posicion2 (* num_productos *) : integer;
  opcion: char;

procedure lee_producto(var mi_producto: producto);
         begin
              write('Nombre: ');
              readln(mi_producto.nombre);
              write('Cantidad: ');
              readln(mi_producto.num_unidades);
              write('Precio: ');
              readln(mi_producto.precio_unidad);
              mi_producto.en_cesta:= true;

              writeln;
         end;

procedure escribe_producto(var mi_producto: producto);
         begin
              writeln('Nombre: ',mi_producto.nombre);
              writeln('Cantidad: ',mi_producto.num_unidades);
              writeln('Precio por unidad: ',mi_producto.precio_unidad:0:2);
              writeln('Precio total: ',(mi_producto.num_unidades*mi_producto.precio_unidad):0:2);
         end;

procedure inicializa_cesta(var mi_cesta: cesta);
         var
            i: integer;

         begin
              for i:=1 to tamxcesta do
                  mi_cesta[i].en_cesta:= false;
         end;

procedure mostrar_cesta(var mi_cesta: cesta);
         var
            i: integer;

         begin
              writeln('Lo producto de la cesta son:');
              writeln;

              for i:=1 to tamxcesta do
                  if (mi_cesta[i].en_cesta=true) then
                     begin
                          writeln('Producto: ',i);
                          escribe_producto(mi_cesta[i]);

                          writeln;
                     end;
         readln;
         clrscr;
         end;

procedure cuenta_productos(var mi_cesta: cesta);
         var
            i: integer;

         begin
              num_productos:= 0;

              for i:=1 to tamxcesta do
                  if (mi_cesta[i].en_cesta=true) then
                     num_productos:= num_productos+1;

              write('En la cesta hay ',num_productos,' productos.');
         readln;
         clrscr;
         end;

procedure busca_libre(var mi_cesta: cesta; var exito: boolean; var posicion2: integer);
         var
            i: integer;

         begin
              i:=0;
              repeat
                    i:=i+1;
                    exito:= mi_cesta[i].en_cesta=false;
                    posicion2:=i;
              until (exito) or (i=tamxcesta);
         end;

procedure incluir_producto_en_cesta(var mi_cesta: cesta; var exito: boolean; var posicion2: integer);
         var
            i: integer;

         begin
              busca_libre(mi_cesta, exito, posicion2);

              i:= posicion2;

              if exito then
                 begin
                      writeln('Introduzca los datos de su nuevo producto:');
                      writeln;
                      lee_producto(mi_cesta[i]);
                      writeln('Se ha añadido su nuevo producto.');
                 end
              else
                  write('La cesta esta llena.');
         readln;
         clrscr;
         end;

procedure buscar_producto(var mi_cesta: cesta; var exito2: boolean; nombre_producto: string; var posicion: integer);
         var
            i: integer;

         begin
              i:=0;
              repeat
                    i:=i+1;
                    exito2:=mi_cesta[i].nombre=nombre_producto;
                    posicion:=i;
              until (exito2) or (i=tamxcesta);
         end;

procedure eliminar_producto_de_cesta(var mi_cesta: cesta; var nombre_producto: string; var exito2: boolean; var posicion: integer);
         var
            i: integer;

         begin
         write('Introduzca el producto que quiere eliminar: ');
         readln(nombre_producto);

         writeln;

         buscar_producto(mi_cesta, exito2, nombre_producto, posicion);

         i:= posicion;

         if exito2 then
            begin
                 mi_cesta[i].en_cesta:=false;
                 writeln('El producto ha sido eliminado.');
            end
         else
             write('Producto no se ha encontrado.');
         readln;
         clrscr;
         end;

procedure modificar_producto(var mi_cesta: cesta; nombre_producto: string; exito2: boolean; posicion: integer);
         var
            opcion: char;
            i: integer;

         begin
         write('Introduzca que producto quiere modificar: ');
         readln(nombre_producto);

         writeln;

         buscar_producto(mi_cesta, exito2, nombre_producto, posicion);

         i:= posicion;

         if exito2 then
            begin
                 clrscr;
                 repeat
                       writeln('A continuacion, puede ver que datos del producto puede cambiar.');
                       writeln;
                       writeln('1. Nombre');
                       writeln('2. Cantidad');
                       writeln('3. Precio');
                       writeln('4. Finalizar modificacion');

                       writeln;

                       write('Elija que datos quiere cambiar: ');
                       readln(opcion);
                       clrscr;

                       if (opcion='1') then
                          begin
                               write('Introduzca un nuevo nombre para el producto: ');
                               readln(mi_cesta[i].nombre);

                               writeln;

                               writeln('Su modificacion se ha realizado con exito.');
                               readln;
                          end;
                       clrscr;

                       if (opcion='2') then
                          begin
                               write('Introduzca una nueva cantidad del producto: ');
                               readln(mi_cesta[i].num_unidades);

                               writeln;

                               writeln('Su modificacion se ha realizado con exito.');
                               readln;
                          end;
                       clrscr;

                       if (opcion='3') then
                          begin
                               write('Introduzca el nuevo precio del producto: ');
                               readln(mi_cesta[i].precio_unidad);

                               writeln;

                               writeln('Su modificacion se ha realizado con exito.');
                               readln;
                          end;
                       clrscr;
                 until (opcion='4');
            end
         else
             begin
                  write('Producto no se ha encontrado.');
                  readln;
             end;
         clrscr;
         end;

procedure cesta_de_compra(mi_cesta: cesta);
         var
            opcion: char;
            i: integer;

         begin
              repeat
                    writeln('A continuacion, elija la opcion que desear.');

                    writeln;

                    writeln('a.  Añadir producto a la cesta.');
                    writeln('b.  Eliminar producto de la cesta.');
                    writeln('c.  Mostrar cesta.');
                    writeln('d.  Modificar producto de la cesta.');
                    writeln('e.  Contar productos de la cesta.');
                    writeln('f.  Volver.');

                    writeln;

                    write('Elije una de las opciones anteriores: ');
                    readln(opcion);
                    clrscr;

                    if ((opcion='a') or (opcion='A')) then
                       incluir_producto_en_cesta(mi_cesta, exito, posicion2);

                    if ((opcion='b') or (opcion='B')) then
                       begin
                            if (num_productos=0) then
                               begin
                                    write('No hay productos en la cesta.');
                                    readln;
                               end;
                               clrscr;

                            if (num_productos>0) then
                               eliminar_producto_de_cesta(mi_cesta, nombre_producto, exito2, posicion);
                       end;

                    if ((opcion='c') or (opcion='C')) then
                       begin
                            if (num_productos=0) then
                               begin
                                    write('No hay productos en la cesta.');
                                    readln;
                               end;
                               clrscr;

                            if (num_productos>0) then
                               mostrar_cesta(mi_cesta);
                       end;

                    if ((opcion='d') or (opcion='D')) then
                       begin
                            if (num_productos=0) then
                               begin
                                    write('No hay productos en la cesta.');
                                    readln;
                               end;
                               clrscr;

                            if (num_productos>0) then
                               modificar_producto(mi_cesta, nombre_producto, exito2, posicion);
                       end;

                    if ((opcion='e') or (opcion='E')) then
                       cuenta_productos(mi_cesta);

                    num_productos:= 0;

                    for i:=1 to tamxcesta do
                        if (mi_cesta[i].en_cesta=true) then
                           num_productos:= num_productos+1;

              until ((opcion='f') or (opcion='F'));
         end;

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

         begin
              write('Introduzca el nombre de la cesta: ');
              readln(Nfichero);

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

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

              close(fichero);
              clrscr;
         end;

procedure recupera_cesta(var Nfichero: string);
         var
            fichero: Tfichero;
            i: integer;
            mi_producto: producto;

         begin
              write('Introduzca el nombre de la cesta: ');
              readln(Nfichero);

              i:=0;

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

              while not eof(fichero) do
                    begin
                         read(fichero, mi_producto);

                         i:=i+1;

                         if (mi_producto.en_cesta=true) then
                            mi_cesta[i]:=mi_producto;
                    end;
              close(fichero);
         end;

begin
    inicializa_cesta(mi_cesta);
    writeln('Bienvenido a su cesta de la compra.');
    readln;
    clrscr;

    repeat
          writeln('1. Abrir cesta de compra existente.');
          writeln('2. Comenzar cesta de compra nueva.');
          writeln('3. Añadir producto a la cesta.');
          writeln('4. Eliminar producto de la cesta.');
          writeln('5. Guardar cesta.');
          writeln('6. Pedir cesta.');
          writeln('7. Salir del programa.');

          writeln;

          write('Elija una de las opciones anteriores: ');
          readln(opcion);
          clrscr;

          if (opcion='1') then
             recupera_cesta(Nfichero);

          if (opcion='2') then
             cesta_de_compra(mi_cesta);

          if (opcion='3') then
             incluir_producto_en_cesta(mi_cesta, exito, posicion2);

          if (opcion='4') then
             eliminar_producto_de_cesta(mi_cesta, nombre_producto, exito2, posicion);

          if (opcion='5') then
             guarda_cesta(mi_cesta, Nfichero);

          if (opcion='6') then
              mostrar_cesta(mi_cesta);

    until (opcion='7');

readln;
end.


03-Jan-2013 21:06
Luis Torres (+12)

Pues a mí sí me funciona. Si quieres me das tu dirección de correo electrónico y te lo envío. Te puedo enviar, además, un video con una corrida.
Saludos.


03-Jan-2013 21:54
Antonio Rodrigues

Te lo he enviado por mensaje.


03-Jan-2013 23:21
Luis Torres (+12)

Ya te los envié a tu correo electrónico.
Saludos.


03-Jan-2013 23:34
Antonio Rodrigues

Ok, gracias amigo. Ahora me pongo a verlos.


03-Jan-2013 23:53
Antonio Rodrigues

Vale, he descubierto porque no funcionaba bien. Resulta que en el procedimiento cesta_de_compra, donde esta el menu secundario, en donde esta la variable mi_cesta le faltaba poner el var y por eso no funcionaba bien.
Bueno, ahora que el problema esta resuelto, voy a terminar el programa. Cuando lo termine lo dejo aqui para que lo prueben y me den su opinion.

Gracias por la ayuda.


04-Jan-2013 00:14
Antonio Rodrigues

Ahora que ya esta resuelto el problema, estoy trabajando en el programa para dejarlo listo, pero me gustaria saber si me puedes dar una ultima ayuda.
Tu ya sabes que para empezar una cesta nueva se utilizar la opcion 2 del menu principal. Luego, tambien esta la opcion 3 del menu principal (añadir producto a cesta) que tambien sirve para empezar una cesta nueva. Lo que me gustaria saber es si hay alguna forma de poner el programa, para que siempre que elijas la opcion 3 del menu principal solo puedas añadir un producto a una cesta ya exitente y que aun no este llena, es decir, poner esa opcion para que no se pueda empezar una cesta nueva con ella ??


04-Jan-2013 02:19
Luis Torres (+12)

Esa acotación te la hice en un mensaje anterior.
Saludos.


04-Jan-2013 02:26
Luis Torres (+12)

Pero en Iniciar una cesta de compra nueva debes inicializar el arreglo nuevamente, porque si ya tienes productos en el arreglo si incluyes un producto dentro de la opción 2 lo agregará al arreglo ya existente. Hay un procedimiento para inicializar el arreglo mi_cesta.

Lo que escribes en tu mensaje, la pregunta que haces, yo creo que ya el programa realiza esta acción. No tendrías que modificar nada.

Saludos.


04-Jan-2013 02:30
Antonio Rodrigues

Bueno, he terminado el programa.

Lo he hecho de 2 formas y dejo aqui las 2 formas para que me puedas dar tu opinion. La forma 1:

program Cesta_de_la_compra;

uses crt;

const
    tamxcesta=3;

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;

var
  mi_producto: producto;
  mi_cesta: cesta;
  nombre_producto, Nfichero: string;
  exito, exito2: boolean;
  posicion, posicion2, num_productos, i: integer;
  opcion: char;

procedure lee_producto(var mi_producto: producto);
         begin
              write('Nombre: ');
              readln(mi_producto.nombre);
              write('Cantidad: ');
              readln(mi_producto.num_unidades);
              write('Precio: ');
              readln(mi_producto.precio_unidad);
              mi_producto.en_cesta:= true;

              writeln;
         end;

procedure escribe_producto(var mi_producto: producto);
         begin
              writeln('Nombre: ',mi_producto.nombre);
              writeln('Cantidad: ',mi_producto.num_unidades);
              writeln('Precio por unidad: ',mi_producto.precio_unidad:0:2);
              writeln('Precio total: ',(mi_producto.num_unidades*mi_producto.precio_unidad):0:2);
         end;

procedure inicializa_cesta(var mi_cesta: cesta);
         var
            i: integer;

         begin
              for i:=1 to tamxcesta do
                  mi_cesta[i].en_cesta:= false;
         end;

procedure mostrar_cesta(var mi_cesta: cesta);
         var
            i: integer;

         begin
              writeln('Los productos de la cesta son:');
              writeln;

              for i:=1 to tamxcesta do
                  if (mi_cesta[i].en_cesta=true) then
                     begin
                          writeln('Producto: ',i);
                          escribe_producto(mi_cesta[i]);

                          writeln;
                     end;
         readln;
         clrscr;
         end;

procedure cuenta_productos(var mi_cesta: cesta);
         var
            i: integer;

         begin
              num_productos:= 0;

              for i:=1 to tamxcesta do
                  if (mi_cesta[i].en_cesta=true) then
                     num_productos:= num_productos+1;

              write('En la cesta hay ',num_productos,' productos.');
         readln;
         clrscr;
         end;

procedure busca_libre(var mi_cesta: cesta; var exito: boolean; var posicion2: integer);
         var
            i: integer;

         begin
              i:=0;
              repeat
                    i:=i+1;
                    exito:= mi_cesta[i].en_cesta=false;
                    posicion2:=i;
              until (exito) or (i=tamxcesta);
         end;

procedure incluir_producto_en_cesta(var mi_cesta: cesta; var exito: boolean; var posicion2: integer);
         var
            i: integer;

         begin
              busca_libre(mi_cesta, exito, posicion2);

              i:= posicion2;

              if exito then
                 begin
                      writeln('Introduzca los datos de su nuevo producto:');
                      writeln;
                      lee_producto(mi_cesta[i]);
                      writeln('Se ha añadido su nuevo producto.');
                 end
              else
                  write('La cesta esta llena.');
         readln;
         clrscr;
         end;

procedure buscar_producto(var mi_cesta: cesta; var exito2: boolean; nombre_producto: string; var posicion: integer);
         var
            i: integer;

         begin
              i:=0;
              repeat
                    i:=i+1;
                    exito2:=mi_cesta[i].nombre=nombre_producto;
                    posicion:=i;
              until (exito2) or (i=tamxcesta);
         end;

procedure eliminar_producto_de_cesta(var mi_cesta: cesta; var nombre_producto: string; var exito2: boolean; var posicion: integer);
         var
            i: integer;

         begin
         write('Introduzca el nombre del producto que quiere eliminar: ');
         readln(nombre_producto);

         writeln;

         buscar_producto(mi_cesta, exito2, nombre_producto, posicion);

         i:= posicion;

         if exito2 then
            begin
                 mi_cesta[i].en_cesta:=false;
                 writeln('El producto ha sido eliminado.');
            end
         else
             write('Producto no se ha encontrado.');
         readln;
         clrscr;
         end;

procedure modificar_producto(var mi_cesta: cesta; nombre_producto: string; exito2: boolean; posicion: integer);
         var
            opcion: char;
            i: integer;

         begin
         write('Introduzca el nombre del producto que quiere modificar: ');
         readln(nombre_producto);

         writeln;

         buscar_producto(mi_cesta, exito2, nombre_producto, posicion);

         i:= posicion;

         if exito2 then
            begin
                 clrscr;
                 repeat
                       writeln('A continuacion, puede ver que datos del producto puede cambiar.');
                       writeln;
                       writeln('   1. Nombre');
                       writeln('   2. Cantidad');
                       writeln('   3. Precio');
                       writeln('   4. Finalizar modificacion');

                       writeln;

                       write(' Elija que datos quiere cambiar: ');
                       readln(opcion);
                       clrscr;

                       if (opcion='1') then
                          begin
                               write('Introduzca un nuevo nombre para el producto: ');
                               readln(mi_cesta[i].nombre);

                               writeln;

                               writeln('Su modificacion se ha realizado con exito.');
                               readln;
                          end;
                       clrscr;

                       if (opcion='2') then
                          begin
                               write('Introduzca una nueva cantidad del producto: ');
                               readln(mi_cesta[i].num_unidades);

                               writeln;

                               writeln('Su modificacion se ha realizado con exito.');
                               readln;
                          end;
                       clrscr;

                       if (opcion='3') then
                          begin
                               write('Introduzca el nuevo precio del producto: ');
                               readln(mi_cesta[i].precio_unidad);

                               writeln;

                               writeln('Su modificacion se ha realizado con exito.');
                               readln;
                          end;
                       clrscr;
                 until (opcion='4');
            end
         else
             begin
                  write('Producto no se ha encontrado.');
                  readln;
             end;
         clrscr;
         end;

procedure cesta_de_compra(var mi_cesta: cesta);
         var
            opcion: char;
            i: integer;

         begin
              repeat
                    writeln('Utiliza este menu para añadir productos, eliminar productos o modificarlos.');

                    writeln;

                    writeln('   a. Añadir producto a la cesta.');
                    writeln('   b. Eliminar producto de la cesta.');
                    writeln('   c. Mostrar cesta.');
                    writeln('   d. Modificar producto de la cesta.');
                    writeln('   e. Contar productos de la cesta.');
                    writeln('   f. Volver.');

                    writeln;

                    write(' Elije una de las opciones anteriores: ');
                    readln(opcion);
                    clrscr;

                    if ((opcion='a') or (opcion='A')) then
                       incluir_producto_en_cesta(mi_cesta, exito, posicion2);

                    if ((opcion='b') or (opcion='B')) then
                       begin
                            if (num_productos=0) then
                               begin
                                    write('No hay productos en la cesta.');
                                    readln;
                               end;
                               clrscr;

                            if (num_productos>0) then
                               eliminar_producto_de_cesta(mi_cesta, nombre_producto, exito2, posicion);
                       end;

                    if ((opcion='c') or (opcion='C')) then
                       begin
                            if (num_productos=0) then
                               begin
                                    write('No hay productos en la cesta.');
                                    readln;
                               end;
                               clrscr;

                            if (num_productos>0) then
                               mostrar_cesta(mi_cesta);
                       end;

                    if ((opcion='d') or (opcion='D')) then
                       begin
                            if (num_productos=0) then
                               begin
                                    write('No hay productos en la cesta.');
                                    readln;
                               end;
                               clrscr;

                            if (num_productos>0) then
                               modificar_producto(mi_cesta, nombre_producto, exito2, posicion);
                       end;

                    if ((opcion='e') or (opcion='E')) then
                       cuenta_productos(mi_cesta);

                    num_productos:= 0;

                    for i:=1 to tamxcesta do
                        if (mi_cesta[i].en_cesta=true) then
                           num_productos:= num_productos+1;

              until ((opcion='f') or (opcion='F'));
         end;

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);

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

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

procedure recupera_cesta(var Nfichero: string);
         var
            fichero: Tfichero;
            i: integer;
            mi_producto: producto;

         begin
              writeln('Esta opcion sirve para abrir una cesta guardado antes.');
              writeln('Para poder modificar la cesta se debe utilizar el menu principal.');
              writeln;
              writeln('Para abrir la cesta, introduzca el nombre de la cesta a continuacion:');
              writeln;
              write('Nombre: ');
              readln(Nfichero);

              i:=0;

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

              while not eof(fichero) do
                    begin
                         read(fichero, mi_producto);

                         i:=i+1;

                         if (mi_producto.en_cesta=true) then
                            mi_cesta[i]:=mi_producto;
                    end;
              close(fichero);
              writeln;
              writeln('Su cesta esta abierta.');
              readln;
              clrscr;
         end;

procedure comenzar_cesta();
         begin
              inicializa_cesta(mi_cesta);
              writeln('Esta opcion sirve para crear una cesta de la compra nueva desde 0.');
              writeln('No te olvides que cada cesta solo puede tener hasta ',tamxcesta,' productos.');
              readln;
              clrscr;

              cesta_de_compra(mi_cesta);
         end;

procedure modificar_prod();
         begin
              writeln('Esta opcion es para modificar los productos de una cesta ya existente.');
              writeln('Si quieres empezar una esta nueva utiliza la opcion 2 (Comenzar cesta de compra nueva) y no esta.');
              readln;
              clrscr;

              cesta_de_compra(mi_cesta);
         end;

procedure ver_cesta();
         begin
              writeln('Con esta opcion puedes ver los productos de la cesta abierta en este momento.');
              writeln('Para ver los productos de otra cesta primero debes abrir dicha cesta.');
              readln;
              clrscr;

              mostrar_cesta(mi_cesta);
         end;

begin
    writeln('--------------------------------- HOLA ---------------------------------');
    readln;
    clrscr;
    writeln('------------------------ Bienvenido a PromCesta ------------------------');
    writeln;
    writeln('El programa donde puedes crear y gestionar tu propia cesta de la compra.');
    readln;
    clrscr;

    repeat
          writeln('Aqui tienes el menu donde puedes empezar una cesta nueva, o modificar una ya existente.');
          writeln;
          writeln('   1. Abrir cesta de compra existente.');
          writeln('   2. Comenzar cesta de compra nueva.');
          writeln('   3. Modificar producto de la cesta.');
          writeln('   4. Guardar cesta.');
          writeln('   5. Pedir cesta.');
          writeln('   6. Salir del programa.');

          writeln;

          write(' Elija una de las opciones anteriores: ');
          readln(opcion);
          clrscr;

          if (opcion='1') then
             recupera_cesta(Nfichero);

          if (opcion='2') then
             comenzar_cesta();

          if (opcion='3') then
             modificar_prod();

          if (opcion='4') then
             guarda_cesta(mi_cesta, Nfichero);

          if (opcion='5') then
             begin
                  if (num_productos=0) then
                     begin
                          write('No hay productos en la cesta.');
                          readln;
                     end;
                     clrscr;

                  if (num_productos>0) then
                     ver_cesta();
             end;

          num_productos:= 0;

          for i:=1 to tamxcesta do
              if (mi_cesta[i].en_cesta=true) then
                 num_productos:= num_productos+1;

    until (opcion='6');

readln;
end.


---------------------------------------------------------------
---------------------------------------------------------------
---------------------------------------------------------------


Aqui la forma 2:

program Cesta_de_la_compra;

uses crt;

const
    tamxcesta=3;

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;

var
  mi_producto: producto;
  mi_cesta: cesta;
  nombre_producto, Nfichero: string;
  exito, exito2: boolean;
  posicion, posicion2, num_productos, i: integer;
  opcion: char;

procedure lee_producto(var mi_producto: producto);
         begin
              write('Nombre: ');
              readln(mi_producto.nombre);
              write('Cantidad: ');
              readln(mi_producto.num_unidades);
              write('Precio: ');
              readln(mi_producto.precio_unidad);
              mi_producto.en_cesta:= true;

              writeln;
         end;

procedure escribe_producto(var mi_producto: producto);
         begin
              writeln('Nombre: ',mi_producto.nombre);
              writeln('Cantidad: ',mi_producto.num_unidades);
              writeln('Precio por unidad: ',mi_producto.precio_unidad:0:2);
              writeln('Precio total: ',(mi_producto.num_unidades*mi_producto.precio_unidad):0:2);
         end;

procedure inicializa_cesta(var mi_cesta: cesta);
         var
            i: integer;

         begin
              for i:=1 to tamxcesta do
                  mi_cesta[i].en_cesta:= false;
         end;

procedure mostrar_cesta(var mi_cesta: cesta);
         var
            i: integer;

         begin
              writeln('Los productos de la cesta son:');
              writeln;

              for i:=1 to tamxcesta do
                  if (mi_cesta[i].en_cesta=true) then
                     begin
                          writeln('Producto: ',i);
                          escribe_producto(mi_cesta[i]);

                          writeln;
                     end;
         readln;
         clrscr;
         end;

procedure cuenta_productos(var mi_cesta: cesta);
         var
            i: integer;

         begin
              num_productos:= 0;

              for i:=1 to tamxcesta do
                  if (mi_cesta[i].en_cesta=true) then
                     num_productos:= num_productos+1;

              write('En la cesta hay ',num_productos,' productos.');
         readln;
         clrscr;
         end;

procedure busca_libre(var mi_cesta: cesta; var exito: boolean; var posicion2: integer);
         var
            i: integer;

         begin
              i:=0;
              repeat
                    i:=i+1;
                    exito:= mi_cesta[i].en_cesta=false;
                    posicion2:=i;
              until (exito) or (i=tamxcesta);
         end;

procedure incluir_producto_en_cesta(var mi_cesta: cesta; var exito: boolean; var posicion2: integer);
         var
            i: integer;

         begin
              busca_libre(mi_cesta, exito, posicion2);

              i:= posicion2;

              if exito then
                 begin
                      writeln('Introduzca los datos de su nuevo producto:');
                      writeln;
                      lee_producto(mi_cesta[i]);
                      writeln('Se ha añadido su nuevo producto.');
                 end
              else
                  write('La cesta esta llena.');
         readln;
         clrscr;
         end;

procedure buscar_producto(var mi_cesta: cesta; var exito2: boolean; nombre_producto: string; var posicion: integer);
         var
            i: integer;

         begin
              i:=0;
              repeat
                    i:=i+1;
                    exito2:=mi_cesta[i].nombre=nombre_producto;
                    posicion:=i;
              until (exito2) or (i=tamxcesta);
         end;

procedure eliminar_producto_de_cesta(var mi_cesta: cesta; var nombre_producto: string; var exito2: boolean; var posicion: integer);
         var
            i: integer;

         begin
         write('Introduzca el nombre del producto que quiere eliminar: ');
         readln(nombre_producto);

         writeln;

         buscar_producto(mi_cesta, exito2, nombre_producto, posicion);

         i:= posicion;

         if exito2 then
            begin
                 mi_cesta[i].en_cesta:=false;
                 writeln('El producto ha sido eliminado.');
            end
         else
             write('Producto no se ha encontrado.');
         readln;
         clrscr;
         end;

procedure modificar_producto(var mi_cesta: cesta; nombre_producto: string; exito2: boolean; posicion: integer);
         var
            opcion: char;
            i: integer;

         begin
         write('Introduzca el nombre del producto que quiere modificar: ');
         readln(nombre_producto);

         writeln;

         buscar_producto(mi_cesta, exito2, nombre_producto, posicion);

         i:= posicion;

         if exito2 then
            begin
                 clrscr;
                 repeat
                       writeln('A continuacion, puede ver que datos del producto puede cambiar.');
                       writeln;
                       writeln('   1. Nombre');
                       writeln('   2. Cantidad');
                       writeln('   3. Precio');
                       writeln('   4. Finalizar modificacion');

                       writeln;

                       write(' Elija que datos quiere cambiar: ');
                       readln(opcion);
                       clrscr;

                       if (opcion='1') then
                          begin
                               write('Introduzca un nuevo nombre para el producto: ');
                               readln(mi_cesta[i].nombre);

                               writeln;

                               writeln('Su modificacion se ha realizado con exito.');
                               readln;
                          end;
                       clrscr;

                       if (opcion='2') then
                          begin
                               write('Introduzca una nueva cantidad del producto: ');
                               readln(mi_cesta[i].num_unidades);

                               writeln;

                               writeln('Su modificacion se ha realizado con exito.');
                               readln;
                          end;
                       clrscr;

                       if (opcion='3') then
                          begin
                               write('Introduzca el nuevo precio del producto: ');
                               readln(mi_cesta[i].precio_unidad);

                               writeln;

                               writeln('Su modificacion se ha realizado con exito.');
                               readln;
                          end;
                       clrscr;
                 until (opcion='4');
            end
         else
             begin
                  write('Producto no se ha encontrado.');
                  readln;
             end;
         clrscr;
         end;

procedure cesta_de_compra(var mi_cesta: cesta);
         var
            opcion: char;
            i: integer;

         begin
              repeat
                    writeln('Utiliza este menu para añadir productos, eliminar productos o modificarlos.');

                    writeln;

                    writeln('   a. Añadir producto a la cesta.');
                    writeln('   b. Eliminar producto de la cesta.');
                    writeln('   c. Mostrar cesta.');
                    writeln('   d. Modificar producto de la cesta.');
                    writeln('   e. Contar productos de la cesta.');
                    writeln('   f. Volver.');

                    writeln;

                    write(' Elije una de las opciones anteriores: ');
                    readln(opcion);
                    clrscr;

                    if ((opcion='a') or (opcion='A')) then
                       incluir_producto_en_cesta(mi_cesta, exito, posicion2);

                    if ((opcion='b') or (opcion='B')) then
                       begin
                            if (num_productos=0) then
                               begin
                                    write('No hay productos en la cesta.');
                                    readln;
                               end;
                               clrscr;

                            if (num_productos>0) then
                               eliminar_producto_de_cesta(mi_cesta, nombre_producto, exito2, posicion);
                       end;

                    if ((opcion='c') or (opcion='C')) then
                       begin
                            if (num_productos=0) then
                               begin
                                    write('No hay productos en la cesta.');
                                    readln;
                               end;
                               clrscr;

                            if (num_productos>0) then
                               mostrar_cesta(mi_cesta);
                       end;

                    if ((opcion='d') or (opcion='D')) then
                       begin
                            if (num_productos=0) then
                               begin
                                    write('No hay productos en la cesta.');
                                    readln;
                               end;
                               clrscr;

                            if (num_productos>0) then
                               modificar_producto(mi_cesta, nombre_producto, exito2, posicion);
                       end;

                    if ((opcion='e') or (opcion='E')) then
                       cuenta_productos(mi_cesta);

                    num_productos:= 0;

                    for i:=1 to tamxcesta do
                        if (mi_cesta[i].en_cesta=true) then
                           num_productos:= num_productos+1;

              until ((opcion='f') or (opcion='F'));
         end;

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);

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

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

procedure recupera_cesta(var Nfichero: string);
         var
            fichero: Tfichero;
            i: integer;
            mi_producto: producto;

         begin
              writeln('Esta opcion sirve para abrir una cesta guardado antes.');
              writeln('Para poder modificar la cesta se debe utilizar el menu principal.');
              writeln;
              writeln('Para abrir la cesta, introduzca el nombre de la cesta a continuacion:');
              writeln;
              write('Nombre: ');
              readln(Nfichero);

              i:=0;

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

              while not eof(fichero) do
                    begin
                         read(fichero, mi_producto);

                         i:=i+1;

                         if (mi_producto.en_cesta=true) then
                            mi_cesta[i]:=mi_producto;
                    end;
              close(fichero);
              writeln;
              writeln('Su cesta esta abierta.');
              readln;
              clrscr;
         end;

procedure comenzar_cesta();
         begin
              inicializa_cesta(mi_cesta);
              writeln('Esta opcion sirve para crear una cesta de la compra nueva desde 0.');
              writeln('No te olvides que cada cesta solo puede tener hasta ',tamxcesta,' productos.');
              readln;
              clrscr;

              cesta_de_compra(mi_cesta);
         end;

procedure anadir_prod();
         begin
              writeln('Esta opcion es solo para añadir productos a una cesta ya existente.');
              writeln('Si quieres empezar una cesta nueva por favor elige la opcion 2 (Comenzar cesta de compra nueva).');
              writeln;
              writeln('No te olvides que solo puedes añadir un producto nuevo si la cesta aun no esta llena.');
              readln;
              clrscr;

              incluir_producto_en_cesta(mi_cesta, exito, posicion2);
         end;

procedure eliminar_prod();
         begin
              writeln('Esta opcion solo sirve para eliminar el producto de la cesta abierta en este momento.');
              writeln('Si quiere eliminar el producto de otro cesta primero debe abrir dicha cesta.');
              readln;
              clrscr;

              eliminar_producto_de_cesta(mi_cesta, nombre_producto, exito2, posicion);
         end;

procedure ver_cesta();
         begin
              writeln('Con esta opcion puedes ver los productos de la cesta abierta en este momento.');
              writeln('Para ver los productos de otra cesta primero debes abrir dicha cesta.');
              readln;
              clrscr;

              mostrar_cesta(mi_cesta);
         end:

begin
    writeln('--------------------------------- HOLA ---------------------------------');
    readln;
    clrscr;
    writeln('------------------------ Bienvenido a PromCesta ------------------------');
    writeln;
    writeln('El programa donde puedes crear y gestionar tu propia cesta de la compra.');
    readln;
    clrscr;

    repeat
          writeln('Aqui tienes el menu donde puedes empezar una cesta nueva, o modificar una ya existente.');
          writeln;
          writeln('   1. Abrir cesta de compra existente.');
          writeln('   2. Comenzar cesta de compra nueva.');
          writeln('   3. Añadir producto a la cesta.');
          writeln('   4. Eliminar producto de la cesta.');
          writeln('   5. Guardar cesta.');
          writeln('   6. Pedir cesta.');
          writeln('   7. Salir del programa.');

          writeln;

          write(' Elija una de las opciones anteriores: ');
          readln(opcion);
          clrscr;

          if (opcion='1') then
             recupera_cesta(Nfichero);

          if (opcion='2') then
             comenzar_cesta();

          if (opcion='3') then
             anadir_prod();

          if (opcion='4') then
              begin
                   if (num_productos=0) then
                      begin
                           write('No hay productos en la cesta.');
                           readln;
                      end;
                      clrscr;

                   if (num_productos>0) then
                      eliminar_prod();
              end;

          if (opcion='5') then
             guarda_cesta(mi_cesta, Nfichero);

          if (opcion='6') then
             begin
                  if (num_productos=0) then
                     begin
                          write('No hay productos en la cesta.');
                          readln;
                     end;
                     clrscr;

                  if (num_productos>0) then
                     ver_cesta();
             end;

          num_productos:= 0;

          for i:=1 to tamxcesta do
              if (mi_cesta[i].en_cesta=true) then
                 num_productos:= num_productos+1;

    until (opcion='7');

readln;
end.


04-Jan-2013 04:07
Luis Torres (+12)

Por favor, envíamelo a mi correo.
Saludos.


04-Jan-2013 10:18
Antonio Rodrigues

Ok.


06-Jan-2013 11:52
Nacho Cabanes (+30)

Personalmente, hay algunos planteamientos que no me gustan:

El paso de parámetros por referencia debería usarse sólo cuando haya que devolver más de un dato, o bien si se pasan datos de un gran tamaño (por ejemplo, un array muy grande) y se quiere optimizar la velocidad.

Por eso, en procedimientos como "procedure escribe_producto(var mi_producto: producto);", que escriben datos y no modifican nada, sería preferible que el parámetro no se pasara por referencia: "procedure escribe_producto(mi_producto: producto);"

Del mismo modo, procedimientos que devuelven un único valor por referencia serían más naturales si estuvieras rescritos como funciones: "function lee_producto: producto;"

También es MUY peligroso dejar (tantas) variables globales. Por ejemplo, puede llegar a ser razonable en un programa pequeño que algo como "mi_cesta" sea global, pero nunca es aceptable que una variable "i", usada típicamente como contador, sea global. También es peligroso que variables como "exito" sean globales, porque puede dar efectos colaterales no deseados si en algún punto se te olvida reiniciar su valor.

Algunas construcciones repetitivas que usas se pueden compactar. Por ejemplo:

 
if (num_productos=0) then
  begin
       write('No hay productos en la cesta.');
       readln;
  end;
  clrscr;
 
if (num_productos>0) then
  ver_cesta();
 



quedaría mejor como

 
if (num_productos>0) then
    ver_cesta();
else
    begin
       write('No hay productos en la cesta.');
       readln;
    end;
 



Aun así, en general está bastante bien para estar empezando, tiene un nivel de dificultad razonable, que te permite practicar un poco de todo.


06-Jan-2013 22:40
Antonio Rodrigues

Nacho Cabanes, agradezco tus consejos porque son muy bienvenidos.
Yo estoy ya casi terminando pascal, pero aun soy un novato y aun tengo mucho que aprender.

Voy a revisar el programa y intentare corregir alguna cosas como tu has dicho.

Pero hay cosas, como por ejemplo lo que has dicho de poner en ves de procedimientos funciones que tengo que dejar asi, porque este programa esta hecho siguiendo los ejercicios y todos me piden que haga procedimientos.


07-Jan-2013 16:10
Antonio Rodrigues

Bueno, seguro que cuando habeis visto mi programa os habeis fijado que en la tabla cesta va desde 0 hasta tamxcesta y no desde 1 y que el 0 nunca lo he utilizado

(cesta=array[0..tamxcesta] of producto).

Pues bueno, ahora he llegado a la ultima actividad donde tengo que utilizar la cesda del 0.
Aqui es donde estoy teniendo algunos problemas.

Este es el significado que tiene el elemento 0:

"Considere a partir de ahora que cuando se realice un pedido, el elemento cero de la cesta (del pedido) tendrá un significado especial:

1. El campo en_cesta:=TRUE significará que el pedido se ha realizado y, por tanto, ya no se puede modificar ningún elemento de la cesta.

2. El campo para el nombre, en esta posición cero, guardará la fecha del pedido.

3. El campo del número de elementos guardará el número de unidades totales del pedido (suma de las unidades de cada producto).

4. El campo de precio guardará el precio total del pedido."

Y este es el ejercicio que tengo que hacer:

"Codifique un procedimiento (calcula_pedido) que en el registro cero de la cesta actualice todos los valores de forma adecuada. Si lo considera oportuno, puede crear procedimientos para realizar cada uno de los cálculos (calcula_unidades, calcula_precio…).

Recuerde que a partir de la invocación de calcula_pedido el campo en_cesta de la posición cero de la cesta hay un TRUE significa que el pedido está hecho y no se pueden hacer modificaciones en la cesta (estará prohibido añadir, borrar productos o cambiar los datos de un producto)."

Esto es lo que he hecho:

procedure calcula_pedido(var mi_cesta: cesta);
         procedure calcula_unidades(var mi_cesta: cesta);
                   var
                      i, unidades_total: integer;

                   begin
                        unidades_total:=0;

                        for i:=1 to tamxcesta do
                            unidades_total:=unidades_total+mi_cesta[i].num_unidades;

                        mi_cesta[0].num_unidades:= unidades_total;
                   end;

         procedure calcula_precio(var mi_cesta: cesta);
                   var
                      i: integer;
                      precio_total: real;

                   begin
                        precio_total:=0;

                        for i:=1 to tamxcesta do
                            precio_total:= precio_total + mi_cesta[i].precio_unidad;

                        mi_cesta[0].precio_unidad:= precio_total;
                   end;

         begin
              mi_cesta[0].nombre:= 'ola';
              calcula_unidades(mi_cesta);
              calcula_precio(mi_cesta);
              mi_cesta[0].en_cesta:= true;
         end;

Lo que me gustaria saber es si esta bien hecho o le falta algo ??



13-Jan-2013 11:11
Nacho Cabanes (+30)

Parece estar bien.

Lo de hacer dos funciones auxiliares (y anidadas) me parece "matar moscas a cañonazos" porque no veo que haga el fuente más legible y además, tienes que recorrer los datos dos veces: una para calcular total de unidades y otra para calcular el precio total, cuando se podría haber hecho en un único "for". Pero bueno... si es por practicar, puede venir bien.

Eso de reservar la ficha 0 (que ya me sorprendió al mirar el fuente completo) para datos globales de toda la cesta me parece una alternativa muy poco legible. Sería mucho más natural usar variables específicas, pero supongo que el profesor que lo haya propuesto, lo habrá hecho para que os resulte más sencillo volcar todo a fichero y leer todo de fichero de forma repetitiva... o simplemente para que practiquéis...


13-Jan-2013 14:02
Antonio Rodrigues

Si yo pienso lo mismo.






(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.)