java-entrada-salida-scanner-println-console

Entrada y salida en Java: System.out y Scanner

  • 4 min

La entrada y salida reúne los mecanismos con los que un programa recibe datos y comunica resultados.

Hasta ahora, nuestros programas no recibían datos del exterior. Definíamos variables dentro del código, calculábamos algo y lo mostrábamos. Una aplicación interactiva necesita preguntar al usuario y responder.

Hoy vamos a ver el I/O (Input/Output) básico en consola.

Parece sencillo, pero Java tiene sus peculiaridades. Si vienes de C# (Console.ReadLine) o Python (input), verás que en Java leer del teclado requiere un pequeño “ritual” con la clase Scanner.

Salida de datos: System.out

Ya conocemos a nuestro viejo amigo System.out.println. Pero vamos a destriparlo un poco más, porque hay vida más allá del println.

System.out es un flujo de salida estándar (Standard Output Stream) que ya viene abierto y listo para usar.

Variantes de impresión

  1. println() (Print Line): Imprime el texto y añade un salto de línea al final.
  2. print(): Imprime el texto y se queda esperando en la misma línea.
  3. printf() (Print Formatted): Si vienes de C, te resultará familiar. Permite formatear texto usando marcadores.
int edad = 25;
double altura = 1.75;

System.out.print("Hola, ");
System.out.println("usuario.");
// Salida: Hola, usuario. (con salto de línea al final)

// Usando concatenación clásica (un poco feo)
System.out.println("Tienes " + edad + " años y mides " + altura + "m.");

// Usando printf (más limpio y profesional)
System.out.printf("Tienes %d años y mides %.2fm.%n", edad, altura);
Copied!

En printf, %d es para enteros, %f para flotantes (podemos limitar decimales con %.2f), %s para textos y %n es el salto de línea multiplataforma.

Entrada de datos: la clase Scanner

Java no tiene una función global simple para leer (como cin en C++). En su lugar, usa la clase java.util.Scanner, que es un analizador de texto.

Scanner es muy potente: puede leer de la consola, de un archivo de texto o de una cadena, y es capaz de trocear la información (tokens) automáticamente.

Paso 1: importar e inicializar

Scanner no está en el paquete básico java.lang, así que hay que importarlo.

import java.util.Scanner; // 1. Importar

public class Main {
    public static void main(String[] args) {
        // 2. Crear una instancia conectada al teclado (System.in)
        Scanner scanner = new Scanner(System.in);

        // ... usar el scanner ...

        // 3. Buena práctica: cerrar el scanner al terminar
        scanner.close();
    }
}
Copied!

Paso 2: leer datos

El Scanner tiene métodos específicos para cada tipo de dato primitivo.

System.out.print("Introduce tu edad: ");
int edad = scanner.nextInt();     // Lee un entero

System.out.print("Introduce tu peso: ");
double peso = scanner.nextDouble(); // Lee un double (ojo con usar coma o punto según tu idioma)

System.out.print("Introduce tu nombre: ");
String nombre = scanner.next();     // Lee UNA sola palabra (hasta el primer espacio)
Copied!

Atención con la configuración regional (Locale): Si tu ordenador está en español, scanner.nextDouble() esperará una coma (2,5) como separador decimal. Si escribes un punto (2.5), lanzará una excepción InputMismatchException. Puedes forzar el punto con scanner.useLocale(Locale.US);.

Leer líneas completas

Si quieres leer una frase entera (con espacios), scanner.next() no sirve porque se para al primer espacio. Debes usar scanner.nextLine().

El salto de línea pendiente en Scanner

Este es el error con el que todos nos hemos golpeado al aprender Java. Presta atención.

Si mezclas métodos de lectura de números (nextInt, nextDouble) con lectura de líneas (nextLine), ocurrirá algo extraño:

System.out.print("Dime un número: ");
int numero = scanner.nextInt();

System.out.print("Dime una frase: ");
String frase = scanner.nextLine(); // ¡El programa se salta esto!

System.out.println("Leído: " + numero + " y " + frase);
Copied!

¿Qué ha pasado?

  1. Escribes 42 y pulsas Enter.
  2. En el buffer de entrada hay: 42 + \n (el salto de línea).
  3. nextInt() coge el 42, pero deja el \n en el buffer.
  4. Llamas a nextLine(). Esta función lee hasta encontrar un salto de línea. Como lo primero que encuentra es el \n que sobró antes, piensa: “¡Ah, una línea vacía!”, la consume y termina.

La Solución: Siempre que leas un número y luego vayas a leer un texto, debes hacer una lectura extra para “limpiar” el buffer.

int numero = scanner.nextInt();
scanner.nextLine(); // <--- CONSUMIMOS EL ENTER SOBRANTE (Limpieza)

System.out.print("Dime una frase: ");
String frase = scanner.nextLine(); // Ahora sí funciona
Copied!

La alternativa: la clase Console

Java 6 introdujo System.console(). Es una forma más directa de leer, especialmente diseñada para contraseñas porque no muestra lo que escribes.

Console consola = System.console();

if (consola != null) {
    String usuario = consola.readLine("Usuario: ");
    char[] pass = consola.readPassword("Contraseña: ");
}
Copied!

El problema de Console

Seguramente si pruebas el código anterior en IntelliJ o Eclipse, te dará error (NullPointerException). Esto es porque System.console() solo funciona si ejecutas el programa desde una terminal real (CMD, Bash). Los IDEs suelen envolver la consola y System.console() devuelve null.