Pascal y ficheros...

Iniciado por Corso, 24 Enero 2006, 20:55 PM

0 Miembros y 1 Visitante están viendo este tema.

Corso

Problema con otro code...



program cuadros;

type

    Tcuadro=record
              NumCuadro:integer;
              Titulo:string;
              Autor:string;
              Precio:real;
    end;
   
    Tfichero = file of Tcuadro;

procedure lee_cuadro(Var cuadros:Tcuadro);

begin
     writeln;
     write(' Numero de cuadro: ');
     readln(cuadros.NumCuadro);
     write(' Titulo cuadro: ');
     readln(cuadros.Titulo);
     write(' Autor: ');
     readln(cuadros.Autor);
     write(' Precio: ');
     readln(cuadros.Precio);
     writeln;
end;

procedure imprime_cuadro(cuadros:Tcuadro);

begin
     writeln;
     writeln(cuadros.NumCuadro,': ',cuadros.Titulo);
     writeln('   Autor: ',cuadros.Autor);

     if cuadros.Precio=0 then
        writeln('   Precio: No en venta')
     else
         writeln('   Precio: ',cuadros.Precio:0:2);

     writeln('---');
end;

procedure graba_fichero(nombre:string; VAR cuadros:Tcuadro);

var
   fichero:Tfichero;

begin
     assign (fichero, nombre);
     rewrite(fichero);
     
     write(fichero, cuadros);
     close(fichero);
end;

procedure lee_fichero(nombre:string; VAR cuadros:Tcuadro);

var
   fichero:Tfichero;
   
begin
     assign(fichero, nombre);
     reset(fichero);
     
     read(fichero, cuadros);
     close(fichero);

end;

var
   cuadro1:Tcuadro;
   cuadro2:Tcuadro;
   nombre:string;
   opcion:char;

begin
 
     write('Introducir por teclado (T) o leer de fichero (F)?');
     readln(opcion);
     
     if opcion='T' then

     begin
          writeln('> Datos primer cuadro');
          lee_cuadro(cuadro1);
          writeln('> Datos segudno cuadro');
          lee_cuadro(cuadro2);

          write('Nombre del fichero donde guardar?');
          readln(nombre);
          graba_fichero(nombre, cuadro1);
          graba_fichero(nombre, cuadro2);
     end
     else

         if opcion='F' then

            begin
                 write('Nombre del fichero donde leer?');
                 readln(nombre);
                 lee_fichero(nombre,cuadro1);
                 lee_fichero(nombre,cuadro2);
            end;


end.




Como veis, lo que hace el programa, es pedir si kieres meter los datos por el teclado, o usar un fichero para leerlo... Lógicamente la primera vez que se ejecute el programa, se tendrá que elegir la opción T, para meter los datos.
Estos datos son escritos en un fichero... Hasta aquí parece que todo fuca bien.

Poro cuando llamo otra vez al programa, y le doy la opción F (fichero), para que me muestre por pantalla los datos que hay en ese fichero, se termina la ejecución del programa, sin mostrar nada...

Por que? Y como lo hago?

Salu2.
Cualquier ciudad es un secreto. Toda palabra traza un laberinto. De cualquier laberinto se sale con palabras.



jvchino

El código que has hecho es un poco difícil de modificar, necesita hacer muchos arreglos para lograr los resultados que deseas.  Luego verás los motivos.

Primero:
No te muestra los datos porque no se lo indicas.  ¿Qué te parece si empleas la sentencia "WRITE"?

procedure lee_fichero(nombre:string; VAR cuadros:Tcuadro);
var
   fichero:Tfichero;
   
begin
  assign(fichero, nombre);
  reset(fichero);
  read(fichero, cuadros);
  writeln(cuadros.numcuadro);
  writeln(cuadros.titulo);
  writeln(cuadros.autor);
  writeln(cuadros.precio:2:2);
  close(fichero)
end;


O mejor aún empleas el procedimiento "imprime_cuadro"

procedure lee_fichero(nombre:string; VAR cuadros:Tcuadro);
var
   fichero:Tfichero;
   
begin
  assign(fichero, nombre);
  reset(fichero);
  read(fichero, cuadros);
  imprime_cuadro(cuadros);
  close(fichero)
end;


Ejecuta ahora el programa y verás los resultados.  ¿No es lo que esperabas... verdad?
Eso sucede porque tu archivo solo tiene guardado un registro, debido a que la sentencia "rewrite" (reescribir) abre un archivo, borra todo su contenido y graba los nuevos datos.
Es decir cuando se ejecuta esta línea: graba_fichero(nombre, cuadro1); se guardan los datos del cuadro1 correctamente.
Pero en la siguiente línea: graba_fichero(nombre, cuadro2); está el error. Ya que se abre el archivo, se destruye su contenido y se reemplaza por los del segundo cuadro.  Con lo cual al final el archivo tendrá un solo registro con los datos del cuadro2.

Posibles Soluciones
1) Abrir el fichero y no cerrarla hasta que se ingresen todos los datos.
   Más o menos así:
   Si se trata del primer cuadro
     Abrir fichero
     Escribir datos
     Dejar el fichero abierto
   Si se trata del segundo fichero
     Escribir datos
     Cerrar fichero


procedure graba_fichero(nombre:string; VAR cuadros:Tcuadro; ind:integer);
var
   fichero:Tfichero;

begin
     if ind=1 then
      begin
        assign (fichero, nombre);
        rewrite(fichero)
      end;

     write(fichero, cuadros);

     if ind=2 then
       close(fichero);
end;



   Una modificación similar debes hacer en el procedimiento "lee_fichero"


2) Otra opción (mucho mejor que la anterior) es el uso de un array de registros    Type
      Tcoleccion = array[1..tamcoleccion] of Tcuadro
   ...
Var
      todosloscuadros:Tcoleccion;



   Un array que almacene los datos de todos los cuadros, así el procedimiento, quedaría:

procedure graba_fichero(nombre:string; todosloscuadros:Tcoleccion);
var
   fichero:Tfichero;

begin
  assign(fichero,nombre);
  rewrite(fichero);
  for i:=1 to tamcoleccion do
     write(fichero,todosloscuadros[i]);
  close(fichero);
end;



Saludos.
Si ayudo a una sola persona a tener esperanza, no habré vivido en vano.

No, nada llega tarde, porque todas las cosas
tienen su tiempo justo, como el trigo y las rosas

skapunky

Hola corso, yo me uno a ayudarte en esto, me ha extrañado una cosa... y esque tal como esta planteado el programa, el record solo sirve para introducir datos una vez. Tendrias de declarar una variable que fuera como un contador, no se llamala "i" y que puedas ir añadiendo varios cuadros, porque tal como has puesto el codigo sirve para rellenar el registro completo de un solo cuadro.

Tendras de hacer estas modificaciones:

1º Declarar

           var
           i:integer;

2º Poner el contador de cuadros, primero un i:=0 y una vez leid a la fichas del cuadro poner i:= i+1.

3º En los readln de las características del cada cuadro, tendras de poner esta sintaxis:

              (cuadros.numcuadro)
y asi para todo el record.También en los writeln.


- Yo hize un programa identico a este y lo hize poniendo lo que te dicho, asi puedes poner opciones para leer los datos de x cuadro y añadirle mejoras de busqueda.

Un saludo.
                   
Killtrojan Syslog v1.44: ENTRAR