#!/usr/bin/ruby
puts "Introduce dos numeros separados por espacios ? "
n, t = gets.strip.split
n, t = n.to_i(), t.to_i()
puts "Has introducido #{n} y #{t} "
puts "Introduce 10 numeros separados por espacios ? "
a = gets.strip.split(" ").map(&:to_i)
puts "Has introducido :"
a.each do |x|
print "#{x} "
end
puts
STDOUT.flushRuby también lee los datos como cadenas de caracteres que tenemos que
segmentar y convertir en el tipo de dato que nos interese, tras
eliminatr el retorno de carro utilizando el método strip.
Los distintos valores en la cadena se pueden separar fácilmente
utilizando el método split, que utilizará el espacio como
separador.
Ruby ofrece una función
scanfal estilo C que también podemos utilizar para leer datos y convertirlos al formato adecuado en un solo paso.require 'scanf' n, y = STDIN.scanf ("%d %d")Si bien, este tipo de procesado de valores puede resultar útil en algunos casos es poco habitual su uso en Ruby
La clase string nos proporciona el método
.to_i (TO Integer, o a entero) para convertir la cadena de
caracteres en un entero. Este método devuelve el valor numérico o 0 si
la conversión no se ha podido realizar.
Sin embargo, el método .to_i no nos permite detectar con
seguridad entradas incorrectas. En esos casos debemos utilizar el método
Integer que generará una excepción en el caso de que se
produzca un error durante la conversión.
input = gets.chomp
begin
n = Integer(input)
rescue ArgumentError
puts "Invalid input"
endDe esta forma podemos detectar errores fácilmente y actuar en consecuencia.
Para capturar una excepción en Ruby, debemos de meter el código que queremos proteger en un bloque
beginendy añadir la secciónrescuepara procesar los errores.
Otra forma de procesar los valores de entrada y asegurarnos que
tienen el formato que queremos es utilizando expresiones regulares con
el método match?. El siguiente fragmento de código nos
muestra como usarlas:
input = gets.chomp
if m = input.match(/\A(\d+)\s+(\d+)\z/)
a = m[1].to_i
b = m[2].to_i
endEn caso de que no estéis familiarizados con las expresiones regulares aquí tenéis la explicación:
\Arepresenta el inicio de una cadena. Es similar a^, si bien, este símbolo está asociado a una “nueva línea”, mientras que\Arepresenta el inicio de una cadena.\z, igual que\Apero para el final de la cadena. Misma diferencia con$\d+indica uno o más (eso significa el+) dígitos (\d).\s+indica uno o más (+) espacios (\srepresenta espacios, tabuladores y retornos de línea)
Las sub-expresiones entre paréntesis serán retornadas por el método como un array. En nuestro ejemplo, los primeros parámetros representa el primer número (uno o mas digitos) y el segundo, el segundo número. Ambos separados por espacios que serán ignorados en los valores de retorno puesto que están fuera de los bloques de paréntesis.
Ruby permite nombrar los bloques de las expresiones regulares. Fijaos en el siguiente código:
m = input.match(/\A(?<a>-?\d+)\s+(?<b>-?\d+)\z/) a = m[:a].to_i b = m[:b].to_iLa expresión anterior además incluye la posibilidad de leer números negativos (
-?significa que el menos es opcional). El primer grupo se a llamadoay el segundob. Posteriormente nos referimos a ellos usando esos nombres.
Si bien, el uso de expresiones regulares es muy potente y puede que
sea la mejor opción, especialmente cuando sea necesario procesar
ficheros con formatos muy concretos, para el caso que nos ocupa, la
entrada de datos sencilla, el uso de split es mucho más
conveniente.
Cuando el número de valores que queremos leer es elevado, podemos
utilizar el metodo map con el que aplicar una función a
todos los datos del array que nos devuelve split. El
ejemplo al principio usa .to_i para la conversión
numérica,
a = gets.strip.split(" ").map( |x| Integer(x))En este caso hemos usado una función lambda como parámetro a
map. Cada elemento del array retornado por
split se pasará como parámetro x a la función
Integer(x), efectivamente convirtiendo las cadenas en
valores numéricos y lanzando una excepción en caso de que alguna entrada
no sea correcta.
Resumen
- La lectura de datos de la consola se realiza como cadenas de caracteres que es necesario trocear y convertir al tipo adecuado
- Los métodos
strip,splity.to_inos permiten, fácilmente, leer valores enteres desde una cadena de caracteres - El método
Integer()además de convertir la cadena en entero, lanza una excepción si se produce cualquier tipo de error sobre la conversión. - Podemos utilizar expresiones regulares para procesar las cadenas de entrada cuando los datos tengan formatos más complejos.
- Ruby ofrece una función del tipo
scanfsimilar a C
■
