Scanner "pulando etapas"

Bom, primeiramente boa noite, venho aqui pedir ajuda para tirar uma dúvida.

— Ao executar uma série de instruções utilizando uma referencia"input" a um objeto do tipo Scanner, a JVM começa a “pular” algumas das instruções do Scanner, como ocorre de maneira semelhante em C, utilizando o scanf… em C a solução seria o fflush(stdin).

As soluções encontradas para resolver problema foram:

  1. criar uma segunda referencia “input2” a um objeto do tipo Scanner.
    O problema é que o primeiro Scanner ao ser utilizado sempre irá pular, como se ainda estivesse com a informação anterior no buffer.

  2. Scanner "pulando etapas"
    Nesse post, um usuario faz descrição de um problema semelhante, porém com o tipo double e a solução recomendada é que em vez de chamar o método “setPreco” no caso assim produtos.setPreco(scanner.nextDouble()); ele o faça da seguinte forma:
    produtos.setPreco( Double.ParseDouble( scanner.nextLine() ) );
    Como aplicar a resolução para os outros tipos primitivos, como no caso em questão, String?

  3. Um nextLine com uma linha em branco. 	
    	(Achei esse método muito "gambiarrento", mas aparentemente é o mais utilizado)	
    

Já aproveitando o post, o que poderia ser melhorado no código?

import java.util.Scanner;

public class Funcionario {

Scanner input = new Scanner(System.in);

private String nome;
private String departamento;
private double salario;
private String dataAdmissao;
private String rg;

//Metodo responsavel por cadastrar cada funcionario
void cadastraFuncionario(){
	System.out.println("Entre com o nome do funcionario: ");
	setNome(input.nextLine());
	System.out.println("Entre com o departamento do funcionario: ");
	setDepartamento(input.nextLine());
	System.out.println("Entre com o salario do funcionario: ");
	setSalario(input.nextDouble());
	System.out.println("Entre com a data de admissao do funcionario: ");
	input.nextLine();
	setDataAdmissao(input.nextLine());
	System.out.println("Entre com o RG do funcionario: ");
	setRG(input.nextLine());
}

public void setNome(String nome){
	this.nome = nome;
}

public String getNome(){
	return nome;
}

public void setDepartamento(String departamento){
	this.departamento = departamento;
}

public String getDepartamento(){
	return departamento;
}

public void setSalario(double salario){
	this.salario = salario;
}

public double getSalario(){
	return salario;
}

public void setDataAdmissao(String dataAdmissao){
	this.dataAdmissao = dataAdmissao;
}

public String getDataAdmissao(){
	return dataAdmissao;
}

public void setRG(String rg){
	this.rg = rg;
}

public String getRG(){
	return rg;
}

public void recebeAumento(double porcentoAumento){
	double aumentoSalarial;
	porcentoAumento /= 100;
	aumentoSalarial = this.salario * porcentoAumento;
	this.salario += aumentoSalarial;
}

public double calculaGanhoAnual(){
	return this.salario *12;
}

}

Aparentemente eu escrevi demais e acabei por não dizer qual seria a dúvida…

A dúvida em questão é a seguinte:

Quais dos 3 métodos acima seria o mais indicado para solucionar o problema?
Existiriam outras opções que possam da mesma ou de melhor forma resolver o problema?

Rahmon_Marcossi Não estou vendo erro no sei código, quando eu estava começando no java o Professor disse para usar 2 Scanner um para o tipo String e outro para o tipo Números, porque dava erro no java se fosse um mesmo Scanner para tipos diferente. String nextLine();,int nextInt(); e double nextDouble();

1 curtida

Voce precisa dar um novo input.
Ex.:

Scanner input = new Scanner (System.in);

setNome (input.nextLine());
//agora você da um novo input
input = new Scanner(System.in);
setSalario(input.nextDouble());
3 curtidas

Tive um problema parecido, e a solucao que encontrei foi apenas usar o input.nextLine( ) para todas as entradas e as que fossem numericas converter com um parse Ex: Integer.parseInt(input.nextLine());

1 curtida

MUITO obrigado, foi a única solução que me ajudou!

usei Scanner input e Scanner input2, para tipos diferentes de atributos :+1:

Embora possa funcionar, esta não é a solução correta.
Quando se lê do teclado, é necessário consumir o enter ao usar qualquer método que não o nextLine().

Assim, deves usar um só objecto scanner e uma de duas opções:

  • Usar sempre nextLine(), convertendo depois para os tipos corretos
  • Usar um nextLine() que não é atribuido a nenhuma váriavel depois de qualquer outro método de scanner, como nextDouble() ou nextInt()

Sei que isso é antigo mas espero que esse professor tenha aprendido ou então que não esteja mais a ensinar hoje em dia…

1 curtida

Essa foi a primeira vez que eu vi essa barbaridade.
Parabéns, a mente humana é realmente capaz de realizar coisas absurdas, tanto para o bem, quanto para o mal.

Na verdade, se você conhece a natureza dos dados que vai ler e entende como o Scanner funciona, não vai precisar usar sempre nextLine(). Por exemplo, uma entrada 1 2 3\n ou 1 2 3<EOF> falharia com um nextInt() e depois um Integer.parseInt( s.nextLine() );

Estava a referir-me a ler do teclado, quando todos os inputs terminam com um enter.
Ao ler de um ficheiro podes (deves) combinar ambos.

1 curtida

O que mais me assusta é que foi um professor que disse isso. Se fosse um zé qualquer no blog dele, ainda vai, mas um professor?

Imagina o nível do curso…

1 curtida

Já vi cada uma de professor que eu sinceramente não duvido. Conheço gente que dá aula de programação e não sabe programar, que o estilo de programação é copia e cola literalmente. É assustador.

2 curtidas

eu ignoro 99 por cento das palavras da questao. E seria direto.
Tanta conversa pra nada.

se alguem consegue complicar as coisas nesse nivel, eh porque ele ainda nao entendeu a essencia da coisa…

Sinceramente não entendi o que vc quis dizer. Fazendo um certo esforço, acredito que vc tentou explicar, da sua maneira, que os fins justificam os meios, ou seja, o código pode estar um lixo e vc não precisa entender o que fez, mas se resolve o problema está ok. Facilmente é possível perceber que esse tipo de abordagem que você adota impacta até na sua forma de escrever e expor suas ideias. Parabéns, pois assim você se torna menos um concorrente para os mais esforçados e que querem entender como as coisas funcionam, pois estarão sempre na sua frente.

1 curtida

Pior que o mercado já está cheio de programador que age e pensa exatamente assim.

Aí o cara que prefere fazer da forma correta às vezes é visto com de forma negativa pelos gestores pois demora demais.

Já trabalhei em empresa onde o gerente de projetos proibia os programadores de tirarem dúvidas com determinado arquiteto pois sabia que havia código ruim e que o arquiteto iria sugerir que fosse refatorado, mas o gerente não queria gastar horas do projeto com refatoração.

Então é fato que com o passar do tempo, o código lixo que simplesmente resolve o problema, acaba virando um estorvo para a empresa, vai implicar em horas de refatoração que não trarão lucro financeiro.

1 curtida