[ Foro de Pascal ]

Ficheros con tipo y sentencia "append"

25-Dec-2010 17:22
Fulanito de Tal
5 Respuestas

Hola de nuevo. Estoy dando mis primeros pasos con ficheros, leyendo, escribiendo, etc. Haciendo un programa casi igual al que está en el tema 11.3. me ha sugido un problema: si introduzco una instrucción "append" en lugar de "rewrite" en un fichero con tipo definido por el usuario, el compilador me da el siguiente mensaje de error (en la línea 14):

Error: Call by var for arg no. 1 has to match exactly: Got "File Of ficha" expected "Text"

Parece como si append sólo pudiera usarse en ficheros de texto.

Me gustaría que me ayudáseis a resolver este tema, porque tengo pensado hacer un programa para llevar una tienda, con fichero de productos, proveedores, etc. Y necesito añadir nuevos registros a los ficheros. Supongo que se puede hacer, a lo mejor es que más adelante en el curso se explicará cómo. Un saludo y gracias de antemano por ayudarme.

Aquí el código:

program probando_agenda;

type ficha = record
  nombre : string [20];
  telefono : string [9];
  end;

var
  fichero : file of ficha;
  ficha_actual : ficha;

begin
  assign (fichero , 'aa.txt');
  append (fichero);

  write ('Nombre: ');
  readln (ficha_actual.nombre);
  write ('Telefono: ');
  readln (ficha_actual.telefono);
  write (fichero , ficha_actual);
 
  close(fichero);
end.


25-Dec-2010 20:09
Antonio P.G.

Hola.

Así, sin haberme repasado nada este tema, te diré alguna cosilla.

Lo primero es que he consultado en un librillo que tengo de Pascal la función "Append" y solamente se puede utilizar sobre variables de tipo "text" (es decir, archivos de texto). Al menos esto es así en la versión 6.0 de Turbo Pascal, y estoy muy seguro de que cuando programaba en la versión 7.0 era de la misma forma.

Con respecto a la primera instrucción que hace tu programa, "Assign", decirte que la extensión del archivo debe ser ".dat" y no ".txt". Esto es porque estás haciendo un archivo de registros o "records".

Por último te diré que "Append" (que lo que hace es abrir un archivo de texto y situar el curso al final de este, de forma que lo que se escriba se añada a continuación de lo que ya estaba) se puede sustituir mediante el uso de algunas funciones que enuncio ahora.

(Yo no recuerdo si existe alguna forma directa de saber cuantos registros tiene un archivo de datos, o archivo con tipo).

Función "FilePos (var F)". "F" es un archivo tipado. Esta función devuelve un número longint que indica el byte de memoria tras el que se encuentra el cursor. Si está al principio del todo, devolverá 0. NOTA: no se puede usar sobre un archivo de texto. El archivo debe estar abierto.

Función "FileSize (var F)". Devuelve el tamaño de un archivo tipado, o archivo de datos, en bytes. NOTA: no se puede usar sobre un archivo de texto. El archivo debe estar abierto.

Función "SizeOf (X)". "X" es una variable o un tipo. Es decir, en tu programa podría ser tanto "ficha" como "ficha_actual". Devuelve el número de bytes que ocupa una variable o tipo.

Por último, está el procedimiento "Seek", que explica el profesor Nacho en la lección.

Con esto, no sería muy difícil saber cuantos registros tiene un archivo. Imaginemos que nuestro archivo tiene un tamaño de 120 bytes, y que el espacio que ocupa nuestro registro es de 12 bytes. Tan sólo con dividir (div) tendríamos:

120 div 12 = 10 registros.

Espero haberte servido de ayuda y espero no haber dicho ninguna tontería. Espero que se me corrija en caso contrario :).

(Por cierto, las funciones están sacadas de un libro).

¡Ciao!


26-Dec-2010 00:05
Fulanito de Tal

Muchas gracias por tu ayuda Antonio. Tengo que ponerme a programar a ver si soy capaz de utilizar esas nuevas funciones. Me parece en principio sencillo. Lo malo es que no sé cómo voy a añadir el nuevo registro al fichero existente, porque si lo abro con reset sólo se puede leer, y si lo abro con rewrite todo lo que había escrito en el fichero se borra.


26-Dec-2010 12:01
Antonio P.G.

Hola.

Me parece que lo dices porque cuando abres con reset, e intentas escribir sobre él, te da error.

Bien, a la hora de manipular información con ficheros tipados, tienes 2 opciones principales.

Opción 1.
Imagina que tienes un fichero con tipo en el disco, y lo vas a manipular. Pues bien, lo que se hace es cargar todos los datos en la RAM, es decir, cargas toda las fichas en variables ficha (que pueden ser tanto en un array como en una lista, claro). Lo que haces entonces es manipular las variables. Al final del programa, antes de terminar, escribes todas esas variables en el archivo y lo cierras para que se guarde.

Opción 2.
Aquí es algo parecido. Lo que haces al principio es copiar a un archivo auxiliar toda la información del original. Éste será el archivo que modificarás durante la ejecución del programa. Luego, antes de terminar, borras el original y le das el nombre del original al nuevo.

Cada opción se mejor para una u otra cosa: espacio y complejidad. Si quieres ahorrar espacio, usa la 2º. Si quieres hacerlo más sencillo, usa la 1º.

Ahora, una pregunta: cuando usas "rewrite", ¿se te borra la información que tenías almacenada? Sé que eso ocurre con los archivos de texto, pero no recuerdo si era igual con los archivos de tipo...

Bueno, que se te dé bien, y si dudas, ya sabes.

¡Ciao!


27-Dec-2010 03:55
Fulanito de Tal

Gracias Antonio una vez más. En los archivos de tipo también se borra la información almacenada si los abres con rewrite. Sin embargo he de decirte que por fin encontré la solución. Hay que abrir el fichero (tiene que existir previamente) con la sentencia reset como si fuera para lectura, y luego te posicionas a continuación del último registro mediante la sentencia seek, entonces escribes el nuevo registro con write(fichero,nuevo_registro). No se puede usar writeln. Es difícil que uno descubra esta solución por sí mismo porque el fichero hay que abrirlo con reset.
Yo lo encontré en un documento pdf que hace meses que tengo en mi ordenador y que hoy me puse a leer buscando otra cosa, es decir que encontré la solución por casualidad. Pero bienvenida sea, porque estuve toda la mañana rompiéndome la cabeza para poder añadir nuevos registros a un fichero de tipo probando de mil formas diferentes. Al final tiré la toalla y tomé la decision de aprender el lenguaje mysql porque en freepascal (creo que) se puede acceder a una base de datos. Tenía pensado escribir los datos en la base de datos y leerlos desde freepascal (cosa que todavía tendría que aprender). Estuve buena parte de la tarde con el mysql. Y ahora a última hora me puse a buscar en pdfs algo que no venía a cuento con los ficheros con tipo y me encontré con esa solución, la probé y funciona.
Por cierto voy a continuar aprendiendo mysql, me está gustando mucho. Pero eso no va a impedir que siga aprendiendo freepascal. No pienso dejarlo.
Gracias de nuevo y hasta pronto!!


28-Dec-2010 19:59
Antonio P.G.

Hola.

Genial todo lo que me cuentas. Yo tuve la asignatura de Bases de Datos en la carrera, y aprendí lenguaje SQL, aunque no lo utilicé desde MySQL, sino desde Microsoft Access. Me gustó.

Gracias por lo de la solución al problema. Espero que ya no se me olvide.

¡Ciao y suerte!






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