Ler dados do teclado com a classe Scanner
Existem diversas classes no Java que permitem a leitura de dados vindos do teclado e a partir do Java 5 a classe java.util.Scanner
forneceu uma facilidade nesse quesito. Porém alguns iniciantes no Java encontram um problema no uso da classe Scanner
, que é o salto de linha. Neste tutorial vamos ver como resolver esse pequeno problema.
1. Criando a classe Teclado
Para iniciar o tutorial vamos criar a classe Teclado
– Listagem 1 – com alguns atributos que serão preenchidos com os dados que serão capturados da leitura do teclado, mais o método toString()
e main()
.
package com.mballem.lerteclado; import java.util.ArrayList; import java.util.List; import java.util.Scanner; public class Teclado { private long id; private String firstName; private String surname; private int age; @Override public String toString() { return "Teclado{" + "id=" + id + ", firstName='" + firstName + '\'' + ", surname='" + surname + '\'' + ", age=" + age + '}' + "\n"; } public static void main(String[] args) { } }
2. Lendo do teclado com Scanner
Agora será criado um método simples para a leitura de dados do teclado, nesse método vou apresentar também o problema do salto de linhas e algumas formas de resolvê-lo. Veja no método readingOne()
– Listagem 2 – que o código aparentemente não apresenta problema algum.
package com.mballem.lerteclado; import java.util.ArrayList; import java.util.List; import java.util.Scanner; public class Teclado { //atributos e toString() omitidos nesta listagem public static void main(String[] args) { readingOne(); } private static void readingOne() { Scanner scanner = new Scanner(System.in); Teclado t = new Teclado(); System.out.print("Enter your id: "); t.id = scanner.nextInt(); System.out.print("Enter your first name: "); t.firstName = scanner.nextLine(); System.out.print("Enter your last name: "); t.surname = scanner.nextLine(); System.out.print("Enter your age: "); t.age = scanner.nextInt(); System.out.println(t.toString()); } }
O código da Listagem 2 quando for executado vai resultar no problema exibido na Figura 1. Veja na marcação em vermelho que após o id
ser informado, a linha first name
não foi digitada e sim a linha surname
. Isso aconteceu porque o método nextInt()
da classe Scanner
deixa no buffer a instrução da tecla pressionada, ou seja, um \n
(123456789\n
). Como o método nextInt()
retorna apenas um valor inteiro, o \n
acaba sendo adicionado ao próximo método que é o nextLine()
. Assim, o método recebe uma instrução como se o usuário tivesse pressionado o e então pula para a próxima linha.
Uma forma para resolver esse problema é substituir o método nextLine()
pelo método next()
, como se pode observar na Listagem 3. Desta forma podemos ler perfeitamente as instruções conforme demonstrado na Figura 2.
package com.mballem.lerteclado; import java.util.ArrayList; import java.util.List; import java.util.Scanner; public class Teclado { //atributos e toString() omitidos nesta listagem public static void main(String[] args) { readingTwo(); } private static void readingTwo() { Scanner scanner = new Scanner(System.in); Teclado t = new Teclado(); System.out.print("Enter your id: "); t.id = scanner.nextInt(); System.out.print("Enter your first name: "); t.firstName = scanner.next(); System.out.print("Enter your last name: "); t.surname = scanner.next(); System.out.print("Enter your age: "); t.age = scanner.nextInt(); System.out.println(t.toString()); } }
Mas ainda temos um problema, o método next()
não permite que se use, por exemplo, o espaço entre palavras. Se for digitado algo como “João Luiz” o método irá separar o nome “João” de “Luiz”, veja o acontece na Figura 3. Observe que na marcação em vermelho, após ter sido digitado o nome “João Luiz” a linha seguinte foi saltada, indo direto para a próxima linha. Porém, quando foi impresso o objeto, o nome “Luiz” apareceu no atributo surname
, o que não deveria ter acontecido.
Uma forma para resolver de vez esse problema do salto de linhas é usar apenas o método nextLine()
, mesmo que um atributo não seja do tipo String
. Bastaria apenas fazer a conversão de tipos, como descrito na Listagem 4. Confira na Figura 4 o resultado da execução do método readingThree()
.
package com.mballem.lerteclado; import java.util.ArrayList; import java.util.List; import java.util.Scanner; public class Teclado { //atributos e toString() omitidos nesta listagem public static void main(String[] args) { readingThree(); } private static void readingThree() { Scanner scanner = new Scanner(System.in); Teclado t = new Teclado(); System.out.print("Enter your id: "); t.id = Long.parseLong(scanner.nextLine()); System.out.print("Enter your first name: "); t.firstName = scanner.nextLine(); System.out.print("Enter your last name: "); t.surname = scanner.nextLine(); System.out.print("Enter your age: "); t.age = Integer.parseInt(scanner.nextLine()); System.out.println(t.toString()); } }
Você pode agora criar um menu pelo teclado, como exemplo veja a Listagem 5.
package com.mballem.lerteclado; import java.util.ArrayList; import java.util.List; import java.util.Scanner; public class Teclado { //atributos e toString() omitidos nesta listagem public static void main(String[] args) { readingMenu(); } private static void readingMenu() { Scanner scanner = new Scanner(System.in); Teclado t; Listlist = new ArrayList (); int option = 0; do { System.out.println("1. Add User"); System.out.println("2. Print Users"); System.out.println("0. Exit"); System.out.print("> "); option = Integer.parseInt(scanner.nextLine()); if (option == 1) { t = new Teclado(); System.out.print("Enter your id: "); t.id = Long.parseLong(scanner.nextLine()); System.out.print("Enter your first name: "); t.firstName = scanner.nextLine(); System.out.print("Enter your last name: "); t.surname = scanner.nextLine(); System.out.print("Enter your age: "); t.age = Integer.parseInt(scanner.nextLine()); list.add(t); } else if (option == 2) { System.out.println(list.toString()); } } while (option != 0); } }
Saiba mais
- Documentação da classe java.util.Scanner http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Scanner.html