Capítulo 2. La génesis de un programa

Contenido:


Pues bien. Usted ya ha leído el Curso de introducción y tiene ante sí el ordenador encendido. Ya sabe cómo hacer que el ordenador repita una tarea varias veces con la instrucción FOR ... NEXT y cómo hacerle realizar operaciones de forma condicional con la instrucción IF... THEN... .

Pero pronto empezará a cansarse de ver su nombre repetido hasta la saciedad en la pantalla y querrá aprender algo de informática más seria, algo útil o divertido. En el capítulo siguiente damos la lista de todas las palabras clave del BASIC de AMSTRAD, junto con su sintaxis, es decir, la forma de utilizarlas. Con estas herramientas en la mano, el único límite a lo que puede obtener del ordenador lo fijará su imaginación.

Si no ha utilizado antes ningún otro ordenador, es probable que la palabra "programación" le suene amenazadora. ¡No le tenga miedo! Programar es más fácil de lo que usted cree, y desde luego mucho más fácil de lo que la jerga técnica da a entender.

No se deje asustar por BASIC y verá qué pronto empieza a disfrutar de la programación y de los frutos de su esfuerzo. Programar puede llegar a ser un ejercicio muy gratificante, en particular para el principiante que se pone a experimentar con la máquina y el lenguaje. Recuerde siempre que, a excepción del riesgo de borrar accidentalmente los discos de CP/M, nada que usted haga en el teclado puede dañar el ordenador; siempre vale la pena intentar algo nuevo.

¿Por dónde empezamos?

En programación, como en muchas otras actividades, lo más difícil es empezar. Sin embargo, lo peor que puede hacer es lanzarse directamente al teclado sin antes pensar para qué.

El primer paso en el desarrollo de un programa debe ser establecer claramente qué se pretende que el programa haga y cómo se quiere que presente los resultados en la pantalla.

Decidido esto, se puede empezar a escribir un programa que realice las funciones deseadas, preocupándose siempre de que el programa discurra suavemente de principio a fin, con el mínimo número de saltos posible. Un buen programa debe ser fácil de leer una vez listado, no un lío indescifrable que haga imposible la detección de errores o la depuración del programa.

Afortunadamente, BASIC es un lenguaje muy tolerante que facilita la depuración de los programas emitiendo mensajes que indican dónde está el error y en qué consiste. Además, hace posible la ampliación de los programas, pues permite intercalar líneas nuevas entre las ya existentes.

Un programa sencillo

Manos a la obra. Vamos a escribir un programa que controle y mantenga un fichero con los nombres y números de teléfono de nuestros amigos. Le llamaremos "guía de teléfonos". Para respetar las reglas que hemos enunciado, "¿qué debe hacer el programa?"; "¿cómo de be presentar los resultados en la pantalla?"

El programa debe permitirnos almacenar 100 nombres y números de teléfono. Cuando queramos averiguar un número de teléfono, escribiremos el nombre y el ordenador nos dará el número. Además, por si no recordamos cómo habíamos escrito algún nombre, el programa debe ser capaz de mostrar toda la información en la pantalla. Dicho sea de paso, esto ya nos hace empezar a pensar en la forma de presentación de los resultados en la pantalla.

De acuerdo, vamos al teclado. Empezaremos por escribir el nombre del programa:

10 REM guia de telefonos

No es imprescindible dar nombre a todos los programas, pero comprobará cuando tenga grabados unos cuantos que es muy útil poder averiguar de un golpe de vista cuál es cuál.

Lo siguiente que necesitamos es poder captar por el teclado (con INPUT) una cadena de caracteres (quizá un nombre) para luego poder asignarlo a una variable. A la variable que represente el nombre le llamaremos NOMBRE$. Lo mismo se puede hacer con el número de teléfono; a la variable le llamaremos TEL$.

¿Recuerda todavía los programas del Curso de Introducción? En algunos de ellos utilizábamos la instrucción INPUT para captar los valores de las variables. Escribamos:

20 INPUT "Escriba el nombre:";NOMBRE$
30 INPUT "Escriba el numero de telefono:";TEL$
run 

En respuesta al programa podemos introducir un nombre (por ejemplo, Juan) y luego un número de teléfono (por ejemplo, 923 233717).

El programa ha almacenado la información que le hemos suministrado, pero no ha escrito ningún resultado en la pantalla. Así pues, en algún lugar del programa necesitaremos instrucciones del tipo

PRINT NOMBRE$ ... y ... PRINT TEL$

con las que recuperemos los valores de las variables.

Algo falla, ¿verdad? Dijimos que nuestro programa debería ser capaz de almacenar 100 nombres con sus números de teléfono; si seguimos por este camino, necesitaremos 200 instrucciones INPUT para escribir la lista en la pantalla. No se inquiete; los ordenadores tienen un recurso que permite manejar con facilidad grandes cantidades de datos: se trata de las "listas". Una lista es una variable que puede representar, con un solo nombre (tal como NOMBRE$), un grupo de datos (en nuestro caso necesitamos 100) que se identifican por un índice. Cuando queramos referirnos a un dato concreto, lo citaremos por el nombre de la variable seguido del índice entre paréntesis; por ejemplo, NOMBRE$(27), donde 27 es el índice y NOMBRES$ es lo que denominamos variable indexada. Si como índice ponemos una variable numérica, NOMBRE$(x), en lugar de un número concreto, podemos manejar la lista completa de datos, del 1 al 100, variando el valor de x dentro de un bucle FOR ... NEXT (v. g., FOR x=1 TO 100). A medida que se va incrementando el valor de x, el índice de NOMBRE$ va señalando los diferentes elementos de la lista.

En nuestro programa necesitamos dos listas, NOMBRE$ y TEL$, cada una con capacidad para 100 elementos. Pero tenemos que informar al ordenador de nuestras intenciones, y para ello debemos dimensionar las listas con la instrucción DIM. Cambiemos las líneas 20 y 30:

20 DIM NOMBRE$(100)
30 DIM TEL$(100)

Ahora ya podemos escribir el tramo del programa que nos va a permitir introducir nombres y números de teléfono. Añada las siguientes líneas:

40 FOR x=1 TO 100
50 INPUT;" Nombre ";NOMBRE$(x)
60 INPUT" Telefono ";TEL$(x)
70 NEXT
run

Pero no es probable que vayamos a introducir los 100 nombres de una vez, y además la forma de presentación en la pantalla es muy desordenada. Tenemos que organizarnos mejor. En primer lugar, antes de captar un nombre, vamos a librarnos de todo el texto superfluo que tenemos en la pantalla:

45 cls

¿Qué podemos hacer para decirle al ordenador que de momento ya no queremos introducir más datos? Podemos detener el programa pulsando [ESC] dos veces, pero cuando volvamos a teclear run perderemos todos los datos introducidos anteriormente.

Ésta es la solución. Cada vez que el programa capte un nuevo nombre, haremos que examine el dato introducido para ver si consta de al menos un carácter o si, por el contrario, es la "cadena vacía". Si lo es, haremos que suspenda la captación de datos. Añada lo siguiente:

55 IF NOMBRE$(x)="" THEN 80
80 PRINT "Fin de la entrada de datos" 

También necesitamos que el ordenador indique al usuario qué debe hacer para suspender la introducción de datos. Añada, pues, la siguiente línea:

47 PRINT "Pulse [RETURN] para terminar"

Ahora vamos a escribir las instrucciones que exhiban en la pantalla la información almacenada. Primero la lista completa:

90 FOR x=1 TO 100
100 PRINT NOMBRE$(x);" ";TEL$(x)
110 NEXT

Otra vez nos ocurre que el programa no sabe dónde pararse y continúa hasta el centésimo elemento. Esto tiene fácil arreglo:

95 IF NOMBRE$(x)="" THEN 120
120 PRINT "Fin de la lista"

La línea 95 comprueba si NOMBRE$(x) es la cadena vacía; si lo es, concluye la escritura de la lista saltando a la línea 120.

Atendamos a los otros requisitos que habíamos formulado al idear el programa. Necesitamos unas instrucciones que busquen en la lista un nombre introducido por el usuario. Escriba lo siguiente:

130 INPUT "Buscar ";BUSCA$
140 FOR x=1 TO 100 
150 IF INSTR(NOMBRE$(x),BUSCA$)=0 THEN 180
160 PRINT NOMBRE$(x);" ";TEL$(x)
170 END
180 NEXT
190 PRINT "No lo encuentro"

En la línea 150 hay una instrucción nueva: INSTR. Esta instrucción determina si la cadena literal BUSCA$ (que es el nombre que estamos buscando, captado en la línea 130) está contenida en NOMBRE$(x). Si no lo está, INSTR genera el valor 0, y entonces el programa salta a la línea 180 para probar con el siguiente valor de x. Si el programa ha examinado sin éxito todos los elementos de la lista, continúa en la línea 190, donde informa de lo que ha ocurrido. En cambio, si encuentra el nombre, INSTR produce un valor mayor que 0, lo que permite que el programa pase de la línea 150 a la 160 para escribir el nombre y el número de teléfono y luego terminar con la instrucción END de la línea 170.

Como ve, nuestro programa avanza muy deprisa, pero todavía nos queda mucho por hacer. Meditemos un poco sobre los inconvenientes de este programa, empezando por el orden en que funciona: primero capta la información, después la escribe completa en la pantalla, luego busca un nombre concreto.

¿Qué ocurre si... ?

Precisamente. ¿Qué ocurre si no queremos que los acontecimientos se produzcan en ese orden? Podríamos querer consultar un teléfono que introdujimos ayer. O podríamos querer ampliar la lista con otros nombres. Esto nos plantea nuevos problemas, para los que tenemos que encontrar solución. Después de todo, en esto es en lo que consiste la programación. Ya hemos dicho que BASIC es muy amable y nos permite rectificar e incluir nuevas instrucciones con gran facilidad; pero un buen programador habría pensado en todo esto de antemano.

Otro grave inconveniente del programa consiste en que las listas quedan almacenadas solamente en la memoria, la cual se borra cada vez que se apaga el ordenador. De poco nos serviría este programa si tuviéramos que escribir todos los datos cada vez que lo ejecutásemos; así pues, necesitamos que el programa pueda grabar los valores de los elementos de NOMBRE$ y TEL$ antes de que apaguemos el ordenador, y también que pueda cargar los datos cada vez que lo ejecutemos.

Soluciones

El primero de los problemas mencionados (el del orden de ejecución) se resuelve haciendo que el programa de la posibilidad de elegir entre las funciones que sabe realizar. De un programa de este tipo se dice que está "controlado por menú" pues, en efecto, ofrece un menú de opciones de entre las cuales se elige la deseada. Si alguna vez ha sacado dinero de un cajero automático, ya ha utilizado un programa de ordenador controlado por menú. Añadamos un menú a nuestro programa:

32 PRINT"1. Introd. datos"
33 PRINT"2. Listado"
34 PRINT"3. Busqueda"
35 PRINT"4. Grabar de datos"
36 PRINT"5. Cargar datos"
37 INPUT "Elija una opción (1-5) ";el
38 ON el GOSUB 40,90,130

85 RETURN
125 RETURN
170 RETURN
200 RETURN

Hemos hecho que el programa escriba la lista de opciones y que capte la elección del usuario mediante una instrucción INPUT para asignarla a la variable el. La instrucción ON el GOSUB de la línea 38 funciona de la siguiente forma: si el=1, invoca la subrutina de la línea 40; si el=2, invoca la subrutina de la línea 90, etc.

Puesto que todas las funciones están ahora en subrutinas (controladas por la instrucción ON el GOSUB), tienen que terminar en una instrucción RETURN. De ahí que hayamos incluido las líneas 85, 125, 170 y 200.

¿Recuerda para qué sirve RETURN? Hace que BASIC retorne de la subrutina a la instrucción siguiente a aquella que invocó la subrutina. En nuestro caso, el punto de retorno es la instrucción siguiente a la línea 38, que es la línea 40. Si dejamos que esto ocurra, el programa entra en la subrutina de "Introducción de datos". Para impedirlo añadimos la línea

39 GOTO 32

que reconduce el programa al menú.

Ejecute el programa y vea cuánto hemos progresado.

Bien; vamos a echar un vistazo al listado. (Detenga el programa pulsando [ESC] dos veces.) Escriba:

LIST

Esto es lo que tenemos por el momento:

10 REM guia de telefonos
20 DIM NOMBRE$(100)
30 DIM TEL$(100)
32 PRINT"1. Introd, datos"
33 PRINT"2. Listado"
34 PRINT"3. Busqueda"
35 PRINT"4. Grabar datos"
36 PRINT"5. Cargar datos"
37 INPUT "Elija una opcion (1-5) ";el
38 ON el GOSUB 40,90,130
39 GOTO 32
40 FOR x=1 TO 100
45 CLS
47 PRINT"Pulse [RETURN] para terminar"
50 INPUT;" Nombre ";NOMBRE$(x)
55 IF NOMBRE$(x)="" THEN 80
60 INPUT;" Telefono ";TEL$(x)
70 NEXT
80 PRINT "Fin de la entrada de datos"
85 RETURN
90 FOR x=1 TO 100
95 IF NOMBRE$(x)="" THEN 120
100 PRINT NOMBRE$(x);" ";TEL$(x)
110 NEXT
120 PRINT "Fin de la lista"
125 RETURN
130 INPUT "Buscar ";BUSCA$
140 FOR x=1 TO 100
150 IF INSTR(NOMBRE$(x),BUSCA$)=0 THEN 180
160 PRINT NOMBRE$(x);" ";TEL$(x)
170 END
180 NEXT
190 PRINT"No lo encuentro"
200 RETURN

Observe que en algunas zonas del programa las instrucciones están muy apretadas y no dejan hueco para introducir otras nuevas. Reorganicemos el programa renumerando las líneas. Escriba:

RENUM
LIST

El listado es ahora:

10 REM guia de telefonos
20 DIM NOMBRE$(100)
30 DIM TEL$(100)
40 PRINT"1. Introd. datos"
50 PRINT"2. Listado"
60 PRINT"3. Busqueda"
70 PRINT"4. Grabar datos"
80 PRINT"5. Cargar datos"
90 INPUT "Elija una opcion (1-5) ";el
100 ON el GOSUB 120,210,270
110 GOTO 40
120 FOR x=1 TO 100
130 CLS
140 PRINT"Pulse (INTRO) para terminar"
150 INPUT;" Nombre ";NOMBRE$(x)
160 IF NOMBRE$(x)="" THEN 190
170 INPUT;" Telefono ";TEL$(x)
180 NEXT
190 PRINT "Fin de la entrada de datos"
200 RETURN
210 FOR x=1 TO 100
220 IF NOMBRE$(x)="" THEN 250
230 PRINT NOMBRE$(x);" ";TEL$(x)
240 NEXT
250 PRINT "Fin de la lista"
260 RETURN
270 INPUT "Buscar ";BUSCA$
280 FOR X=1 TO 100
290 IF INSTR(NOMBRE$(x),BUSCA$)=0 THEN 320
300 PRINT NOMBRE$(x);" ";TEL$(x)
310 END
320 NEXT
330 PRINT"No lo encuentro"
340 RETURN

¡Mucho más limpio! Pero sigamos con el programa. Ahora queremos que cada vez que introduzcamos un dato nuevo (nombre y número), el ordenador lo coloque al final de la lista actual, en el primer lugar que encuentre vacío. En esta ocasión vamos a utilizar la instrucción LEN para determinar la longitud de una cadena literal. Especificaremos lo siguiente:

Si (IF) la longitud de NOMBRE$(x) es mayor que 0, es decir, si ya hay un dato en ese elemento de la lista, entonces (THEN) ir a la línea 180 (que provoca el salto al siguiente elemento de la lista):

135 IF LEN(NOMBRE$(x))>0 THEN 180

Una solución sencilla, ¿verdad? Los problemas de este tipo siempre tienen solución si conocemos bien el repertorio de instrucciones y nos paramos a pensar un poco. Para casi todas las necesidades hay casi siempre al menos una instrucción; cuanto mayor es la experiencia en programación, más inmediatas son las soluciones.

Vamos con otro requisito del programa: grabar los valores de las variables para poder cargarlos más tarde. En la parte 7 del Curso de introducción hemos explicado cómo grabar programas (con la orden SAVE). Pero el programa no es más que la herramienta que nos permite captar y manipular los datos; cuando grabamos el programa sólo estamos guardando la herramienta, no los valores de las variables.

Así pues, tenemos que escribir una sección del programa que grabe los valores de las variables. Para ello crearemos un "fichero de datos".

Lo primero es abrir (OPEN) un fichero en dirección de salida (OUT) dándole el nombre de "datos". Después escribiremos (WRITE) los valores de las variables NOMBRE$(x) y TEL$(x), de 1 a 100, en el fichero; finalmente, cerraremos (CLOSE) el fichero y retornaremos (RETURN) al menú. Pondremos esta rutina en las líneas 350 y siguientes. Para no tener que escribir los números de línea, ejecutaremos la orden

AUTO 350

que inicia la numeración automática de las líneas a partir del número 350:

350 OPENOUT "datos"
360 FOR x=1 TO 100
370 WRITE #9,NOMBRE$(x),TEL$(x)
380 NEXT
390 CLOSEOUT
400 PRINT"Fin de la grabación de los datos"
410 RETURN

Cuando haya terminado de teclear la línea 410 y haya pulsado [RETURN], pulse [ESC] para interrumpir la función AUTO.

Como tenemos una rutina más, tendremos que poner otro número de línea en la instrucción ON el GOSUB de la línea 100. Para ello vamos a corregir (editar, EDIT) la línea 100:

100 ON el GOSUB 120,210,270,350

A partir de ahora, cada vez que elijamos la opción 4 del menú, el programa grabará el fichero de datos en el disco.

Observe la línea 370, en la que se escriben los valores de NOMBRE$(x) y TEL$(x) en el disco: la expresión #9 que aparece después de WRITE es un "indicador de canal" que especifica a qué canal debe el ordenador enviar los datos. El ordenador maneja 10 canales:

Los ocho primeros (#0 a #7) dirigen los datos a la pantalla [bien a la pantalla completa, bien a alguna ventana (WINDOW)].

El canal #8 es el de la impresora.

Finalmente, el canal #9 es el que conecta el ordenador con la unidad de disco; éste es el que utilizamos en la instrucción 370.

Una digresión

Hagamos un cometario sobre la orden AUTO que acabamos de conocer. Si se escribe sencillamente

AUTO

el ordenador empieza a numerar líneas a partir del 10 y va incrementando el número de 10 en 10 cada vez que se pulsa [RETURN]. Si ya existen líneas 10, 20, 30, etc., su contenido aparece en la pantalla según se va pasando por ellas (pulsando [RETURN]).

Cuando aparece una línea en la pantalla, se la puede editar antes de pulsar [RETURN]. Esto da un método para editar cómodamente líneas cuyos números estén uniformemente espaciados.

Volvemos al programa

Ya hemos escrito las instrucciones que graban los datos en disco. Ahora nos falta ocuparnos de la lectura de los datos para ponerlos a disposición del programa. Como vamos a escribir una nueva rutina, tendremos que poner otro número de línea en la instrucción ON el GOSUB. Editemos la línea 100:

100 ON el GOSUB 120,210,270,350,420

Para leer los datos tenemos que empezar por abrir (OPEN) en dirección de entrada (IN) el fichero que tenemos en el disco con el nombre de "datos". Después leemos con INPUT (por el canal #9) los valores de las variables NOMBRE$(x) y TEL$(x), de 1 a 100, y finalmente cerramos (CLOSE) el fichero y retornamos (RETURN) al menú. Escriba las siguientes líneas:

420 OPENIN "datos"
430 FOR x=1 TO 100
440 INPUT #9,NOMBRE$(x),TEL$(x)
450 NEXT
460 CLOSEIN
470 PRINT"Fin de la carga de los datos"
480 RETURN

El fin del principio

Por fin hemos conseguido un programa que realiza todas las funciones previstas. Todo lo que nos queda ahora es ocuparnos de cómo presentar los resultados en la pantalla.

El principio del fin

Para mejorar el manejo de la pantalla vamos a añadir unas cuantas instrucciones:

34 MODE 1

Esta instrucción establece el modo de pantalla y borra la pantalla al principio del programa. Añada ahora lo siguiente:

36 WINDOW #1,13,30,10,14

No se deje impresionar por esta instrucción aparentemente tan complicada. Lo que hemos hecho es definir una ventana en la pantalla para escribir en ella el menú. Después de la palabra WINDOW, lo primero que ponemos es el número del canal al que vamos a asignarla; recuerde que podemos elegir cualquiera entre el 0 y el 7. Ahora bien, si tenemos en cuenta que todos los textos que enviamos a la pantalla sin especificar número de canal circulan por el #0, no vamos a dar este número a nuestra ventana. Elegimos, pues, el número 1. Los cuatro números que vienen a continuación especifican el tamaño de la ventana. Su significado no podía ser más sencillo: columna del borde izquierdo, columna del derecho, primera fila y última fila, por este orden. En nuestro caso, después de especificar el canal #1, hemos dicho al ordenador que la ventana empieza en la columna número 13 y termina en la número 30, en horizontal, y empieza en la fila 10 y termina en la 14, en vertical.

Para dirigir los textos del menú al canal #1 debemos editar las líneas 40 a 80:

40 PRINT #1,"1. Introd. datos"
50 PRINT #1,"2. Listado"
60 PRINT #1,"3. Busqueda"
70 PRINT #1,"4. Grabar datos"
80 PRINT #1,"5. Cargar datos"

Añadamos también

85 LOCATE 7,20

para situar el texto de la línea 90.

Para borrar la pantalla cada vez que el programa retorne al menú, modifiquemos la línea 110:

110 GOTO 34

Además, para borrar la pantalla cada vez que se selecciona una opción del menú añadimos:

95 CLS

Finalmente, incluiremos las tres líneas siguientes para hacer que el retorno al menú sea controlado por el usuario:

103 LOCATE 9,20
105 PRINT "Pulse una tecla para volver al menu"
107 IF INKEY$="" THEN 107

La línea 103 especifica dónde se debe escribir el mensaje de la línea 105. La línea 107 examina el teclado para averiguar si se ha pulsado alguna tecla. Si no se ha pulsado ninguna, INKEY$ genera la cadena vacía y entonces se repite la ejecución de la línea hasta que efectivamente se pulse alguna. Ésta es la forma habitual de programar la espera "hasta que el usuario se decida", pues BASIC no pasa a la línea siguiente mientras no se pulse una tecla.

Bueno, ya hemos terminado. O quizá no, porque podríamos incluir la posibilidad de modificar o borrar nombres y números de teléfono, de ordenarlos alfabéticamente, de listarlos por la impresora, etc. Todas estas mejoras son posibles; podríamos seguir mejorando y depurando el programa indefinidamente, pero en algún momento tenemos que poner el punto y aparte, y éste es tan bueno como cualquier otro. Le dejamos, pues, con este programa de "guía de teléfonos", confiando en haberle abierto las puertas del arte de programar. Adecente el programa con la orden

RENUM

y grábelo en disco; o bórrelo si no le gusta. Quién sabe; quizá pueda necesitarlo algún día.

Listado final:

10 REM guia de telefonos
20 DIM NOMBRE$(100)
30 DIM TEL$(100)
40 MODE 1
50 WINDOW #1,13,30,10,14
60 PRINT #1,"1. Introd. datos"
70 PRINT #1,"2. Listado"
80 PRINT #1,"3. Busqueda"
90 PRINT #1,"4. Grabar datos"
100 PRINT #1,"5. Cargar datos"
110 LOCATE 7,20
120 INPUT "Elija una opcion (1-5) ";el
130 CLS
140 ON el GOSUB 190,290,350,430,500
150 LOCATE 9,20
160 PRINT"Pulse una tecla para volver al menu"
170 IF INKEY$="" THEN 170
180 GOTO 40
190 FOR x=1 TO 100
200 CLS
210 IF LEN(NOMBRE$(x))>0 THEN 260
220 PRINT"Pulse [RETURN] para terminar"
230 INPUT;" Nombre ";NOMBRE$(x)
240 IF NOMBRE$(x)="" THEN 270
250 INPUT;" Telefono ";TEL$(x)
260 NEXT
270 PRINT "Fin de la entrada de datos" 
280 RETURN
290 FOR X=1 TO 100
300 IF NOMBRE$(x)="" THEN 330
310 PRINT NOMBRE$(x);" ";TEL$(x)
320 NEXT
330 PRINT "Fin de la lista"
340 RETURN
350 INPUT "Buscar ";BUSCA$
360 FOR X=1 TO 100
370 IF INSTR(NOMBRE$(x),BUSCA$)=0 THEN 400
380 PRINT NOMBRE$(x);" ";TEL$(x)
390 END
400 NEXT
410 PRINT"No lo encuentro"
420 RETURN
430 OPENOUT "!datos"
440 FOR x=1 TO 100
450 WRITE #9,NOMBRE$(x),TEL$(x)
460 NEXT
470 CLOSEOUT
480 PRINT"Fin de la grabacion de los datos"
490 RETURN
500 OPENIN "!datos"
510 FOR X=1 TO 100
520 INPUT #9,NOMBRE$(x),TEL$(x)
530 NEXT
540 CLOSEIN
550 PRINT"Fin de la carga de los datos"
560 RETURN