7.2.-Entrada/Salida estandar
7.2 Lectura y escritura en consola¶
Después de comprender en 7.1 qué es la entrada/salida, ahora toca trabajar con el caso más cercano y habitual: la consola.
Este apartado está directamente relacionado con el resultado de aprendizaje 5, especialmente con los criterios que piden:
- a) usar la consola para realizar operaciones de entrada y salida.
- b) aplicar formatos en la visualización de la información.
- c) reconocer posibilidades de E/S del lenguaje y sus librerías.
La idea es sencilla: un programa de consola muestra mensajes, pide datos y responde en función de lo que introduce la persona usuaria. Aunque parezca básico, aquí se apoyan muchas prácticas posteriores: validación de datos, mensajes claros, formato de salida y separación entre lógica y presentación.
Qué vas a aprender en este tema
- Escribir mensajes en la salida estándar y de error.
- Leer datos desde teclado con Kotlin.
- Validar conversiones básicas de texto a números.
- Aplicar formato a la salida para que sea más clara y útil.
1. La consola como canal de entrada y salida¶
En una aplicación de consola trabajamos, como mínimo, con tres canales:
- entrada estándar, normalmente el teclado;
- salida estándar, normalmente la consola;
- salida de error, usada para avisos o mensajes de fallo.
En la JVM estos canales se representan mediante:
System.inSystem.outSystem.err
En Kotlin no solemos trabajar directamente con ellos todo el tiempo, porque el lenguaje ofrece funciones más cómodas para el caso habitual de consola.
Idea clave
En este tema no estamos guardando todavía información en ficheros. Aquí nos centramos en la comunicación inmediata entre la persona usuaria y el programa.
2. Escribir información en consola¶
Las funciones más habituales para mostrar texto son print() y println().
print()escribe sin salto de línea final.println()escribe y añade un salto de línea al final.
Salida:
Si necesitas un salto de línea dentro del propio texto, puedes usar \n:
2.1. Plantillas de cadenas¶
En Kotlin, la forma más cómoda de mezclar texto con variables suele ser la interpolación:
val nombre = "Alicia"
val nota = 8.5
println("Alumno: $nombre")
println("Nota final: $nota")
println("El doble de la nota es ${nota * 2}")
Esta técnica hace el código más legible que concatenar muchas cadenas con +.
2.2. Salida de error¶
Cuando quieres diferenciar un mensaje correcto de uno problemático, puedes usar System.err:
No siempre será visible de forma distinta en el terminal, pero conceptualmente es importante porque separa la salida normal de los errores.
3. Leer datos desde teclado¶
En Kotlin actual, para leer una línea completa desde teclado es habitual usar readln() o readlnOrNull().
readln()devuelve unString.readlnOrNull()devuelveString?y permite contemplar el caso en que no haya datos.
3.1. Leer texto¶
Este ejemplo es suficiente cuando esperamos una línea de texto y damos por hecho que la entrada estará disponible.
3.2. Leer números con seguridad¶
El teclado siempre entrega texto. Si queremos obtener un número, primero leemos una cadena y después la convertimos.
La forma más segura para empezar no es toInt(), sino toIntOrNull():
fun main() {
print("Introduce tu edad: ")
val edad = readln().toIntOrNull()
if (edad != null) {
println("Tienes $edad años")
} else {
System.err.println("La edad introducida no es válida")
}
}
También existen:
toDoubleOrNull()toFloatOrNull()toLongOrNull()
3.3. Evita !! al leer datos¶
Es frecuente encontrar ejemplos como este:
o, en ejemplos antiguos:
Funcionan si la entrada es correcta, pero fallan con facilidad cuando la persona usuaria introduce algo inesperado. Para aplicaciones de aprendizaje y para programas robustos, conviene validar.
Error frecuente
Si conviertes directamente con toInt() y la entrada no es un entero válido, obtendrás una excepción en tiempo de ejecución.
3.4. Repetir la petición hasta obtener un dato válido¶
Una mejora muy habitual consiste en seguir preguntando hasta recibir una entrada correcta:
fun main() {
var cantidad: Int? = null
while (cantidad == null) {
print("Introduce una cantidad entera: ")
cantidad = readln().toIntOrNull()
if (cantidad == null) {
System.err.println("Dato no válido. Inténtalo de nuevo.")
}
}
println("Cantidad aceptada: $cantidad")
}
Este patrón aparece mucho en programas de consola y en actividades de clase.
4. Formato de salida¶
Una cosa es que un programa funcione y otra que su salida sea clara. El criterio de evaluación sobre formato no consiste solo en “que imprima algo”, sino en que la información se vea bien y resulte fácil de interpretar.
4.1. Cuándo basta con interpolación¶
Para mensajes sencillos, la interpolación suele ser suficiente:
val producto = "Teclado"
val precio = 19.95
println("Producto: $producto")
println("Precio: $precio €")
4.2. Cuándo usar format¶
Si necesitas controlar decimales, anchos de columna o alineación, es más útil usar format:
Salida:
Algunos especificadores habituales son:
| Formato | Uso habitual |
|---|---|
%s |
texto |
%d |
entero |
%.2f |
decimal con 2 cifras |
%n |
salto de línea |
4.3. Ejemplo de tabla sencilla¶
val articulos = listOf(
"Cuaderno" to 2.5,
"Bolígrafo" to 1.2,
"Mochila" to 24.95
)
println("%-12s | %8s".format("Artículo", "Precio"))
println("-----------------------------")
for ((articulo, precio) in articulos) {
println("%-12s | %8.2f €".format(articulo, precio))
}
Salida:
Artículo | Precio
-----------------------------
Cuaderno | 2.50 €
Bolígrafo | 1.20 €
Mochila | 24.95 €
5. Ejemplo integrador¶
El siguiente programa combina lectura por teclado, validación y formato de salida:
fun main() {
print("Nombre del producto: ")
val producto = readln()
print("Unidades: ")
val unidades = readln().toIntOrNull()
print("Precio unitario: ")
val precio = readln().toDoubleOrNull()
if (unidades == null || precio == null) {
System.err.println("No se puede generar el ticket porque hay datos no válidos.")
return
}
val total = unidades * precio
println()
println("Ticket de compra")
println("------------------------------")
println("Producto: $producto")
println("Unidades: %d".format(unidades))
println("Precio/u: %.2f €".format(precio))
println("Total: %.2f €".format(total))
}
Este ejemplo ya refleja una situación realista de RA5:
- se lee información desde teclado;
- se muestra información en consola;
- se valida la entrada;
- y se cuida el formato de salida.
6. Buenas prácticas¶
Cuando trabajes con consola y teclado, intenta seguir estas ideas:
- muestra mensajes claros antes de pedir cada dato;
- valida los números antes de usarlos;
- no abuses de
!!; - usa
System.errpara errores o avisos; - separa, cuando el programa crezca, la lógica del cálculo y la presentación en consola.
Ampliación
Si necesitas más detalle sobre lectura avanzada, Scanner o variantes históricas como readLine(), consulta 7.2.1. Consola y teclado: ampliación.
7. Resumen¶
En este tema has visto que:
- la consola permite interactuar con la persona usuaria de forma inmediata;
print()yprintln()sirven para mostrar información;readln()yreadlnOrNull()permiten leer desde teclado;- la validación con
toIntOrNull()y similares evita muchos errores; - el formato de salida mejora la claridad y cumple con el criterio de evaluación asociado.
Con esta base ya puedes crear programas sencillos de consola que pidan datos, los validen y muestren resultados de forma clara.