Java - Entrada e Saída de Dados via Console (Programas em Modo Texto)

Constantemente vejo pessoas postando problemas com programas que realizam a entrada de dados pelo teclado utilizando a classe Scanner.

Geralmente esses problemas estão relacionados ao uso indevido dos métodos nextInt, nextByte, nextDouble, nextFloat, nextInt, nextLong e nextShort.

Estes métodos não consomem o caractere de quebra de linha gerado ao pressionar ENTER no teclado e isso gera comportamentos indesejados, pois caso o método nextLine seja chamado após qualquer um desses outros métodos, ele simplesmente vai consumir a quebra de linha que ficou no buffer e vai retornar um String vazio.

A classe Scanner é uma ótima alternativa à classe DataInputStream ao ler arquivos ou streams de dados, mas é uma encrenca ao ler dados no console.

Tendo isto em vista, resolvi disponibilizar em meu GitHub a classe StdIO para encapsular o System.in e System.out do Java, facilitando a leitura e escrita no console.

A classe StdIO possui sobrecargas dos seguintes métodos de leitura e escrita:

StdIO.readBoolean
StdIO.readByte
StdIO.readChar
StdIO.readDouble
StdIO.readFloat
StdIO.readInt
StdIO.readLong
StdIO.readShort
StdIO.readString

StdIO.print
StdIO.printf
StdIO.println

Suas sobrecargas incluem a possibilidade de apresentar uma mensagem durante a leitura e também adicionar predicados que permitem a releitura no caso de valores inválidos.

Vejamos alguns exemplos a seguir:

Lendo um número inteiro:

int numeroInteiro = StdIO.readInt();

Lendo um número inteiro maior que 10:

int numeroInteiro = StdIO.readInt(numero -> numero > 10);

Lendo um número inteiro maior que 10 e menor que 20:

int numeroInteiro = StdIO.readInt(numero -> numero > 10 && numero < 20);

Lendo um número real com mensagem:

double numeroReal = StdIO.readDouble("Informe um número real: ");

Lendo um número real maior que 5.5 com mensagem:

double numeroReal = StdIO.readDouble("Informe um número real maior que 5.5: ", numero -> numero > 5.5);

Lendo um número real maior que 4.5 e menor que 6.5 com mensagem:

double numeroReal = StdIO.readDouble("Informe um número real maior que 4.5 e menor que 6.5: ", numero -> numero > 4.5 && numero < 6.5);

Lendo texto:

String texto = StdIO.readString();

Lendo texto que não pode ser vazio:

String textoDigitado = StdIO.readString(texto -> !texto.trim().isEmpty());

Lendo texto com mensagem:

String textoDigitado = StdIO.readString("Digite seu nome: ");

Lendo texto de no máximo 15 caracteres e com mensagem:

String textoDigitado = StdIO.readString("Digite seu nome (max 15 letras): ", texto -> texto.length() <= 15);

Lendo sexo com possibilidade entre m ou f:

char sexo = StdIO.readChar(letra -> letra == 'm' || letra == 'f');

Lendo sexo com com mensagem:

char sexo = StdIO.readChar("Digite o sexo: ['m' ou 'f'] ", letra -> letra == 'm' || letra == 'f');

As saídas de dados com a classe StdIO são idênticos à utilizar o System.out do Java, mas existem de forma a permitir utilizar uma única classe tanto para entrada quanto para a saída de dados.

Exemplos de saída:

StdIO.println();

StdIO.println("Qualquer coisa com quebra de linha");

StdIO.print("Qualquer coisa sem quebra de linha");

StdIO.printf("Valor real formatado com 2 casas: %.2f", 123.456789);

StdIO.printf("Valor real formatado com 3 casas e quebra de linha: %.3f%n", 9876.54321);

É isso pessoal.
A classe StdIO está disponível em meu GitHub para quem quiser.
Espero que seja útil.
:slight_smile:

5 curtidas