Todo sobre: INPUT Este texto reune todas mis notas sobre la instrucción INPUT y las sentencias relacionadas con la misma, ya sea existentes en otros BASICs o en el Basic Sinclair, asi como sus equivalentes y diferencias en el ZX SPECTRUM. En otros lenguajes de programación FORTRAN usa la instrucción READ. Ejemplo: 10 READ(1,*,END=80)T,P I=I+1 TIEMPO(.l.)=T PROD(I)=P GO TO 10 LISP también usa READ. Ejemplo: (SETQ A (READ)) PASCAL usa igualmente READ y READLN. LOGO tiene las primitivas READ CHAR o CR y READLIST. Creo que para muestra hubo más de un botón. Todo parece indicar que INPUT es exclusivamente del BASIC, así que pasamos a... INPUT Lee un dato del teclado y lo almacena en una variable. La variable puede ser numérica o alfanumérica. Las variables alfanuméricas deben terminar en $. EJM: EDAD; NOMBRE$. Nota: No todas las versiones de Basic admiten variables numéricas o alfanuméricas de nombres largos. En el caso del Basic Sinclair solamente una letra es admitida como nombre de cadena en comparación. El Basic de Dartmouth carecía en sus inicios de esta sentencia. Toda la entrada de datos se hacía mediante READ - DATA. sintaxis 1: INPUT var Esta primera versión de INPUT solamente operaba con variables numéricas. sintaxis 2: INPUT var{$} Luego vendría una mejora al aceptar variables tanto numéricas como cadenas. sintaxis 3: INPUT "texto"; var{$} [{,}{;} var2{$} ...] Esta sería la versión definitiva usada en la gran mayoría de BASICs. sintaxis completa en el Spectrum: INPUT [{#nn;}{AT x,y;}{TAB z;}{INK i;}{PAPER p;}{texto;}{'}{,}{(v[$]);}] v{$} sintaxis completa en el caso del ZX81: INPUT v{$} No acepta más que una variable por instrucción, ni AT ni TAB, menos aun mensajes de texto como el Spectrum. sintaxis completa en el caso del QL: {AT x,y:} INPUT ["texto"{; , !}] var{$}[, var2{$}, ...] LINE INPUT sintaxis: LINE INPUT var$ existente en la mayoría de BASICs basados en Microsoft como es el GW-Basic. No existe sin embargo en los BASICs de Apple, Commodore, BBC y Atari. Su finalidad es leer una línea completa desde el teclado ignorando los delimitadores o separadores de datos como son las comas. Equivalente en Basic Sinclair: INPUT LINE v$ Inexistente en el Basic del ZX81 y el SuperBasic del QL. INPUT$ sintaxis: INPUT$(n) Un cruce entre INPUT e INKEY$. Función. Permite ingresar n caracteres sin verlos en pantalla ni pulsar ENTER al último. Ejemplo: 40 DATA "McKoy","McFarlan","Camborio","Z" 50 n=8 60 PRINT "Introduzca la palabra clave" 70 p$=INPUT$(n) 80 PRINT 90 RESTORE 100 READ c$ 110 IF c$=p$ THEN 150 130 IF c$="Z" THEN PRINT "Palabra clave erronea": GOTO 50 140 GOTO 100 150 PRINT "Palabra de acceso aceptada" 160 ' continua programa... Inexistente en Basic Sinclair. Es posible definirla mediante subrutinas. INPUT# Esta sintaxis siempre ha sido asociada exclusivamente con ficheros OPEN/CLOSE en la gran mayoría de versiones de BASIC. Uso similar en el Spectrum. LINE INPUT #nn;v$ Equivalente en Basic Sinclair: INPUT #nn; LINE v$ Lo mismo pero leyendo todo el contenido salvado en un fichero. Otras diferencias Pasamos ahora a ver qué tanto difiere el INPUT de los otros BASICs con respecto al Basic Sinclair. Ejemplo 1: INPUT n El comportamiento es similar tanto en el BASIC estandar como en el Basic Sinclair, con la diferencia de que suele aparecer un signo ? junto al cursor en espera de que uno tipee algo. Si se desea ver ese signo en el Spectrum hay que hacer INPUT "?";n. Ejemplo 2: INPUT a,b,c El Basic estandar permite que los datos sean ingresados de dos modos: El primero pulsando RETURN tras cada número y el segundo es separando por comas y al final RETURN, como por ejemplo ? 10,20,30 - si se intenta tipear como 10 20 30 normalmente lo tomará como un solo número 102030, ignorando los espacios y quedará a la espera de los otros valores. Los espacios entre números hacen que ATARI se detenga con un mensaje de error. El BBC Micro genera un mensaje pero sigue esperando que se tipee un valor correcto en vez de interrumpir todo como ATARI. El Spectrum no permite separar con comas ni espacios, así que hay que pulsar ENTER tras tipear cada número uno por uno. Ejemplo 3: INPUT n$ En el Basic Sinclair el cursor de INPUT va dentro de unas comillas a diferencia del Basic estandar cuando se trata de cadenas. Ejemplo 4: INPUT a$,b$,c$ El mismo caso que el ejemplo 2. Con la caracteristica de que en el Spectrum tipear datos separados por comas en este caso, haría que todo sea considerado como una sola cadena en vez de tres cadenas distintas. Eso significa que en Basic estandar INPUT no permite textos con comas, lo que nos lleva a... Ejemplo 5: LINE INPUT a$ esto sí permite tipear parrafos con comas dentro del texto sin considerarlos como datos separados. En el Spectrum el equivalente INPUT LINE lo que hace es que no aparezcan las comillas del INPUT alfanumérico y acepta todo lo que uno tipee incluidas las comillas dentro del texto. Ejemplo 6: INPUT "Mensaje";var no todas las versiones de Basic admiten esta sintaxis, lo que obliga en esos casos a tipear PRINT "mensaje";:INPUT var - lo cual nos lleva a la otra singularidad del Spectrum y es que PRINT e INPUT operan en áreas distintas de la pantalla. Para replicar el ejemplo previo, debemos de tipearlo como: PRINT "mensaje";: INPUT var: PRINT var Si quisieramos replicar o simular el modo de ingreso del ejemplo 2 donde las variables están separadas por comas, debemos aplicar algo como: 100 INPUT "ingrese 3 numeros de 2 digitos separados por comas"'z$ 110 LET a= VAL z$(TO 2): LET b= VAL z$(4 TO 5): LET VAL (7 TO) Y en el caso del ejemplo 4, se hace algo similar: 100 INPUT "ingrese 3 nombres de 5 caracteres separados por comas"'z$ 110 LET a$= z$(TO 5): LET b= VAL z$(7 TO 11): LET VAL (13 TO) Pero en el caso de variables de longitud libre, debemos crear una rutina que lea la cadena hasta encontrar una coma, la cual es el separador de datos y extraer el dato hasta allí, y así sucesivamente, hasta leer toda la cadena y por último transfeir los fragmentos a su variable correspondiente. Aunque es más trabajoso, eso nos da el mismo efecto del INPUT de los otros BASICs. Un detalle más: En el caso del primer ejemplo, es posible en el Spectrum ingresar un nombre de variable en vez de un número, o incluso una expresión matemática completa. Eso en los otros micros provoca un error, el cual obliga a pedir de nuevo que se ingrese algo válido o en el caso del BBC y Atari se interrumpe con un error. En el caso del ejemplo 3, cuando aparece el prompt "L", es posible mover el cursor fuera de las comillas y añadir luego algo como ""+a$, con lo cual, de existir esa variable, será usado como dato válido, nuevamente, eso es imposible en los otros BASICs. Si en cambio, se hubiese ingresado una variable numérica válida como "nn+1", esta podría ser ejecutada mediante VAL y en el caso de una variable de cadena como "n$" se usaría VAL$ en cambio. Otro detalle más... En el caso del primer ejemplo si pulsamos RETURN, Atari se detiene con un error, Apple ][ solicita se reingrese un número válido, Oric lo mismo; en cambio BBC, TRS80, C=64, Amstrad, MSX, CoCo y Dragon, devuelven cero al responder solamente con RETURN. El Spectrum en cambio genera el signo ? si se pulsa ENTER y se queda esperando a que uno tipee algo válido. En el caso del ejemplo 3, Apple, Atari, BBC, CoCo y Dragon devuelven la cadena vacía si se pulsa RETURN. Oric se porta igual que en el ejemplo 1, tampoco acepta RETURN como única respuesta a un INPUT de cadena, vuelve a pedir el dato. TRS80, MSX, C=64 devuelven la cadena previa, por lo que hay que dejarla en blanco previamente cada vez que se quiera usar con INPUT. El Spectrum actúa del mismo modo que Apple, devuelve la cadena vacía si se usa ENTER como única rpta. LOS TRUCOS MENOS USADOS CON INPUT A continuación un montón de usos de INPUT en el Spectrum y que son imposibles de hacer (en su mayoría) con otros BASICs cuya sintaxis es más estricta. INPUT ; Como CLS pero exclusivamente para la zona baja Ejemplo: 10 PRINT #0;"Esto es una prueba" 20 PRINT #1;"Prueba #2" 30 PRINT #0;"Prueba #3" 40 PAUSE 0 50 INPUT ;: PRINT #1;"Prueba #4" 60 PAUSE 0 Otro efecto de INPUT ; 10 FOR n=1 TO 100 20 PRINT n: INPUT ; 30 NEXT n INPUT USR Como PRINT USR pero sin imprimir nada en pantalla, óptimo en la zona baja. Ejemplo: 10 INPUT "PULSE ESPACIO"; USR 1415 20 INPUT "pulse cualquier tecla"; USR 5598 INPUT AT Obviamente como PRINT AT pero con un efecto muy singular. Ejemplo: 10 BORDER 6 20 POKE 23659,24 30 PRINT PEEK 23659 40 INPUT AT 0,0; PEEK 23659; AT 22,0;23; AT 10,10;N$ Creo que el ejemplo habla por si sólo. Ahora, no es posible hacer un AT más alla de 22, ya que da error. Es decir que INPUT AT usa 32 x 23 a diferencia de PRINT AT que suele estar limitado a 32 x 22, a menos que 23659 sea puesto a cero. En cuanto al POKE ya dicho, INPUT anula su efecto. Logicamente eso significa que también es válido: 40 PRINT #0; AT 0,0; 1; AT 22,0;23; AT 10,10;"HOLA": PAUSE 0 INPUT# En el Spectrum no se limita a ficheros OPEN/CLOSE. También puede usarse en el caso de la pantalla como hace PRINT#. Ejemplo: si añadimos la sigte. línea al ejemplo anterior de INPUT AT: 50 INPUT #2;"Prueba #5 ";(n$) también la podemos tipear del modo sigte.: 50 INPUT #2;"Prueba #5 "+n$ En suma: el canal 2 tiene solamente 22 líneas, mientras el canal 0 da 23. Por otro lado los ejemplos muestran también cómo insertar variables dentro de INPUT, en el caso de las de cadena con el signo más o dentro de paréntesis. En el caso de los números, igual con paréntesis "";(n) o usando ""+STR$ n. INPUT LINE Mientras que LINE INPUT acepta una variable por cada sentencia, en el Basic Sinclair INPUT acepta varias variables LINE dentro de la sentencia. Ejemplo: 100 INPUT LINE a$,LINE b$,LINE c$ INPUT y cadenas A diferencia de otros BASICs, el Spectrum puede ingresar de frente fragmentos de cadenas y no necesariamente la cadena entera. Es decir que no es necesario "trocearla" luego para insertar algo. Ejemplo: 10 DIM n$(20) 20 INPUT n$(6 TO 10) 30 PRINT n$ De hecho, READ también puede leer las cadenas del mismo modo que INPUT. Ejemplo: 20 READ n$(6 TO 10) INPUT invisible ó a falta de INPUT$ Digamos que quiero tipear algo, pero que no se vea en pantalla... Para ello, basta con hacer la tinta y el papel del mismo color que el borde. Ejemplo: 10 BORDE 0 20 LET X= PEEK 23624 30 POKE 23624,0 40 INPUT #2;"DIGITE UN NUMERO" '#0;N 50 PRINT N 60 POKE 23624,X Aplicando las técnicas previamente vistas: INPUT$ en el Spectrum Ahora, si a pesar de todo se desea esta función, se la puede definir del modo sigte.: subrutina FN input$(n)= DIM i$(n) FOR x=1 TO n PAUSE 0: LET i$(x)= INKEY$ NEXT x: RETURN Otra forma exclusiva de definir la subrutina FN input$(n)= LET i$="" FOR x=1 TO n INPUT USR 5598 LET i$= i$+ CHR$ PEEK 23559 NEXT x: RETURN Ejemplo aplicación de INPUT$: 5 GOTO 50 10 REM subr. FN input$(n)= 11 DIM i$(n) 12 FOR x=1 TO n 13 PAUSE 0: LET i$(x)= INKEY$ 14 NEXT x: RETURN 40 DATA "McKoy","McFarlan","Camborio","Z" 50 LET n=8 60 PRINT "Introduzca la palabra clave" 70 GOSUB 11: LET p$=i$() 80 PRINT 90 RESTORE 100 READ c$ 110 IF c$=p$ THEN GOTO 150 130 IF c$="Z" THEN PRINT "Palabra clave erronea": GOTO 50 140 GOTO 100 150 PRINT "Palabra de acceso aceptada" 160 REM continua programa... De hecho, esta es la única alternativa cuando uno bloquea la línea de edición por motivos de protección. Ya que intentar usar INPUT en esos casos causaría un cuelgue del sistema. Publicado en MICROHOBBY #43, sección TRUCOS (posición con INPUT AT y C.M.): 10 LET abre=(dir_rut_1): LET cierra=(dir_rut_2) 20 FOR i=abre TO abre+4: READ x: POKE i,x:NEXT i 30 FOR i=cierra TO cierra+4: READ x: POKE i,x:NEXT i 40 INPUT "" AND USR abre; AT x,y;n$; "" AND USR cierra 50 DATA 253,54,49,24,201: REM LD (IY+49),24 RET 60 DATA 253,54,49,2,201: REM LD (IY+49),2 RET Las rutinas en C.M. son reubicables, de ahí que se las llame dir_rut 1 y 2, los de MH sugerían que se usen 23296 y 23231. El AT queda a gusto del usuario igualmente. Cambiando el cursor en INPUT 10 INPUT n 20 POKE 23617,n 30 INPUT "Prueba: ";n$ Nota: n= 1 modo E, n= 2 modo G. Otros valores cambian la letra del modo pero no los modos antes vistos. Si n= 238, tendremos un cuadrado parpadeante. Si n= 226 no aparecerá ningún cursor. Saliendo de INPUT e INPUT LINE Y para cerrar, aunque creo que ya es harto conocido, he decidido referenciarlo aquí también. Ejemplo 1: INPUT n - Basta con tipear STOP (SS + A) Ejemplo 2: INPUT n$ - borrar las comillas y hacer STOP como en el ejemplo 1. Ejemplo 3: INPUT LINE a$ - STOP no funciona aquí. Usar Cursor Abajo (CS + 6) Y con esto cierro todas mis notas sobre la sentencia INPUT. (c)2020 zx_if1@hotmail.com