Ejemplos java y C/linux

Tutoriales

Enlaces

Licencia

Creative Commons License
Esta obra está bajo una licencia de Creative Commons.
Para reconocer la autoría debes poner el enlace https://old.chuidiang.org

Lee el teclado en java. Sumar dos números

Ahora que ya sabemos manejar bien todo el tema de compilados, ejecución, paquetes y hacer jars, vamos con un pequeño programa para ver cómo se lee desde teclado. Java es especialmente críptico en esto.

LOS InputStream: EL OBJETO System.in

Al igual que Java nos ofrece System.out para escribir en pantalla, tenemos System.in para leer de ella. System.in es un objeto de una clase de java que se llama InputStream.

Para java, un InputStream es cualquier cosa de la que se leen bytes. Puede ser el teclado, un fichero, un socket, o cualquier otro dispositivo de entrada. Esto, por un lado es una ventaja. Si todas esas cosas son InputStream, podemos hacer código que lea de ellas sin saber qué estamos leyendo.

Por otro lado, es una pega. Como un InputStream es para leer bytes, sólo tiene métodos para leer bytes. Nosotros queremos leer palabras o números del teclado, no bytes. Si escribimos en el teclado una A mayúscula y la leemos con System.in, obtendremos un entero de valor 65, que es el valor del byte correspondiente a la A.

LOS Reader

Para java, una clase Reader es una clase que lee caracteres. Esto se parece más a lo que queremos. Un Reader tiene métodos para leer caracteres. Con esta clase ya podriamos trabajar. La pena es que seguimos teniendo System.in, que es un InputStream y no un Reader.

¿Cómo convertimos el System.in en Reader?. Hay una clase en java, la InputStreamReader, que nos hace esta conversión. Para obtener un Reader, únicamente tenemos que instanciar un InputStreamReader pasándole en el constructor un InputStream. El código es el siguiente

InputStreamReader isr = new InputStreamReader(System.in);

Estamos declarando una variable "isr" de tipo InputStreamReader. Creamos un objeto de esta clase haciendo new InputStreamReader(...). Entre paréntesis le pasamos el InputStream que queremos convertir a Reader, en este caso, el System.in

Ya tenemos el Reader. ¿Cómo funciona exactamente?

LA CLASE BufferedReader

Con la clase InputStreamReader podríamos apañarnos. La pega es que nos da los caracteres sueltos. Si estamos leyendo de teclado, el que usa el programa puede escribir 10 caracteres o 20 o 13. Si usamos InputStreamReader, como lee caracteres sueltos, Tenemos que decirle cuántos queremos (que no lo sabemos), o bien ir pidiendo de uno en uno hasta que no haya más.

Esto es un poco rollo y si sólo tuvieramos la clase InputStreamReader sería un trozo de código que tendriamos que repetir por muchos lados. Para el cado concreto de leer de teclado, sería ideal si hubiese una clase en java que nos lea de golpe todo lo que ha escrito el usuario de nuestro programa y nos lo diera de un golpe.

Como la gente de Java son muy listos, esa clase existe en Java. Se llama BufferedReader. El mecanismo para obtener un BufferedReader a partir de otro Reader cualquiera (por ejemplo el InputStreamReader), es similar al que usamos antes. Lo instanciamos pasándole en el construtor el Reader. El código es

BufferedReader br = new BufferedReader (isr);

El funcionamiento de esta clase es igual que el InputStreamReader. Cuando le pedmos una línea completa de caracteres (un String), ella se lo pide al Reader que tenga dentro, los convierte en String y nos lo devuelve.

Para pedirle un String, se usa el método readLine(). Este método lee todos los caracteres tecleados (recibidos si fuera otro dispositivo de entrada) hasta que encuentra la pulsación de la tecla <INTRO>, <RETURN> o como quieras llamarla.

String texto = br.readLine();

Esto lee del teclado un String completo y lo guarda en una variable "texto".

CONVERTIR LA CADENA String EN UN ENTERO int

Si queremos leer un número del teclado, el usuario escribe por ejemplo 123, con la clase BufferedReader obtendremos un String que contiene "123", es decir, tres caracteres. Eso no se parece en nada a un número 123.

Para convertir el String en un número entero (sin decimales), podemos usar otra clase de Java. La clase Integer vale para muchas cosas, pero entre otras es capaz de convertir un String a int. Siempre que sea posible. Por ejemplo "abc" no se puede convertir a número de ninguna manera.

La clase Integer es muy estricta. Para convertir el String a int necesita que el String sea exactamente un int. Cualquier caracter o letra que tenga el String y no valga, hará que la conversión falle. Por ejemplo, "123a" da fallo por culpa de la "a" del final. Del mismo modo "12 3" da fallo por el espacio entre el "12" y el "3". Bueno, esto en realidad creo que era así de estricto en versiones algo anteriores de java. Las actuales simplemente ignoran lo que va detrás del número.

La conversión se realiza así

int valor = Integer.parseInt(texto);

Esto intenta convertir texto en un int y si no hay problemas, guarda el resultado en una variable int llamada valor.

EXCEPCIONES Exception Y try-catch

Cuando en java puede fallar algo, por ejemplo, la conversión de la cadena en int, suele avisarnos. Esto lo hace "lanzando excepciones". Una excepción es algo que lanza Java para avisarnos que ha habido un problema.

En nuestro código podemos "capturar" esas excepciones y hacer algo para tratar de arreglaro. Por ejemplo, si le pedimos al usuario que meta un número, el usuario escribe "abc", lo leemos e intentamos convertirlo a int, nos salta una excepción. Si capturamos esa excepción, en el código que hagamos para tratarla, podemos avisar al usuario que se ha equivocado un poco al teclear, que lo intente de nuevo y volver a pedirle el número.

Para capturar una excepción, tenemos que hacer el código así

try
{
    // Aquí el código que puede fallar
}
 catch (Exception e)
{
    System.out.println(e);
    e.printStackTrace();
    // Aquí el código para tratar el fallo
}

Lo habitual, al menos mientras estamos haciendo nuestro programa, es sacar por pantalla el error, para tener una pista de qué ha fallado. Eso se puede consiguir de las dos formas que he puesto arriba (y otras muchas)

Por un lado, de la forma que ya conocemos, con System.out.println(e); Esto nos saca una línea de texto con el error correspondiente en inglés del bueno.

Por otro lado, llamando al método printStackTrace() de la excepción que se ha provocado. Esta llamada escribe la misma línea de texto de error, pero además nos dice exactamente en qué línea de código se produce el error. Esta información es muy útil si nuestro programa todavía está a medias y no acaba de hacer lo que queremos.

UN EJEMPLO: SUMAR DOS NÚMEROS

Como ejemplo, vamos a ver un programa completo que pide dos números al usuario, los suma y saca el resultado. El ejemplo es este

import java.io.*;
public class suma
{
    public static void main (String [] args)
    {
        InputStreamReader isr = new InputStreamReader(System.in);
        BufferedReader br = new BufferedReader (isr);

        try
        {
            System.out.print("Sumando 1 : ");
            int s1 = Integer.parseInt(br.readLine());
            System.out.print("Sumando 2 : ");
            int s2 = Integer.parseInt(br.readLine());
            int suma=s1+s2;
            System.out.println ("La suma es " + s1 + "+" + s2 +"="+ suma);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}

Cuando vimos el tema de paquetes, vimos que las clases se pueden agrupar en paquetes. Todas las clases que hemos visto aquí de java relativas a Streams y Readers, están en el paquete java.io. En la primera linea de código, con el import, estamos avisando a java que vamos a usar clases de ese paquete. Es necesario poner esta linea, decirle a java en qué paquetes están las clases, porque en otros paquetes puede haber clases con el mismo nombre, para distinguir unas de otras.

Para verlo funcionando, edita un fichero nuevo que se llame suma.java, copia todo este texto y sálvalo.

Luego lo compilas y lo puedes ejecutar

$ javac suma.java
$ java suma
Sumando 1 : 2
Sumando 2 : 4
La suma es 2+4=6

Si metemos la pata a posta, tendremos esto

$ javac suma.java
$ java suma
Sumando 1 : 2
Sumando 2 : asd
java.lang.NumberFormatException: For input string: "asd"
        at java.lang.NumberFormatException.forInputString(Unknown Source)
        at java.lang.Integer.parseInt(Unknown Source)
        at java.lang.Integer.parseInt(Unknown Source)
        at suma.main(suma.java:14)

Si sabemos un poco de inglés, vemos que obtenemos una excepción "NumberFormatException" para la cadena "asd", es decir, que no puede obtener el número a partir de "asd". En la última línea, vemos que el error se produce en la línea 14 del fichero suma.java, en el método main(). Es decir, si contamos líneas en el código, en la línea

int s2 = Integer.parseInt(br.readLine());

Las otras tres líneas son en las clases de java que se ha producido el error. Normalmente no nos aportan demasiada información.

Estadísticas y comentarios

Numero de visitas desde el 4 Feb 2007:

Aviso Legal