Leer de teclado en Rust

En muchas aplicaciones es necesario leer datos de teclado. Si bien esto podría considerarse sencillo en lenguaje como Python o Ruby, lo cierto es que sí se quiere hacer bien es complicado. Funciones como scanf de C son consideradas inseguras y en Java, hasta la llegada de la clase java.util.Scanner era un dolor de cabeza. En Rust no es distinto, es por ello que muchos tutoriales de Rust obvian esta parte. No obstante, leer de teclado no es tan difícil, como veremos a continuación.

read_line

El método principal para leer de teclado es read_line, que nos lee una línea como String. Para acceder a read_line primero necesitamos tener on objeto stdin. La manera más fácil de hacerlo es usar el módulo std::io.

El procedimiento es el siguiente, en primer lugar creamos una variable de tipo String vacía y mutable donde se va a alojar el resultado, posteriormente leemos y tratamos el resultado.

Como vemos, al leer la línea también se nos guarda el salto de línea. Si queremos quitarlo podemos usar trim.

Este código sin embargo generará una advertencia por el compilador y es que read_line genera devuelve un valor, concretamente un Result, que como vimos, sirven para el manejo de errores en Rust. Si no queremos tratar este Result con especial interés, podemos usar ok y opcionalmente especificar un mensaje de error con expect.

Si quieres tratar el error mejor puedes, pero read_line no suele fallar.

Leyendo enteros

Hasta aquí todo sencillo, porque leíamos String, en lo que entra todo lo que el usuario puede meter. Pero, ¿y si queremos leer un número de teclado? La cosa se complica. Normalmente se lee de teclado como String y luego se intenta pasar a número. Veamos como.

Como vemos, hay que importar std::str::FromStr para tener disponible las operaciones from_str en los tipos elementales. También se observa que hemos hecho un unwrap, porque from_str devuelve un Result. Este error sin embargo conviene que lo tratemos con más cuidado, pues es bastante probable que salte.

Un ejemplo ideal

En este código vamos a ver como pedir un entero, asegurándonos de que el usuario realmente introduce un entero e insistiendo hasta que finalmente introduce un entero válido.

He decidido separar la parte de pedir el número a otra función que devuelve Result para así poder usar el operador ?. También he usado print! y io::stdout().flush() en vez de println! para que tanto el mensaje como la entrada se realice en la misma línea y quede más bonito.

 

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *