Problema besta no main

16 respostas
Andre_Brito

Pessoal, boa tarde (ou noite).

Eu não estou conseguindo achar a razão para a seguinte saída:

No seguinte código:

import java.util.Scanner;
import java.util.ArrayList;

public class Controladora
{
	public void mostrarOpcoes() {
		System.out.println("\n\nOpcoes\n");
		System.out.println("Cadastrar");
		System.out.println("Listar");
		System.out.println("Excluir");
		System.out.println("Sair");
		System.out.print("Digite a sua opcao > ");
	}
	
	
	public static void main(String[] args) {
		Scanner reader = new Scanner(System.in);
		ArrayList<Pessoa> lista = new ArrayList<Pessoa>();
		String opcao;
		Controladora controladora = new Controladora();
		
		do {
			controladora.mostrarOpcoes();
			
			opcao = reader.nextLine();
			opcao = opcao.toLowerCase();
			
			if (opcao.equals("cadastrar")) {
				int numero = 0;
				System.out.println("1 - Funcionario");
				System.out.println("2 - Cliente");
				System.out.print("Digite a sua opcao > ");
				numero = reader.nextInt();
				if (numero == 1) {
					Funcionario f = new Funcionario(1, "Joao da Silva");
					lista.add(f);
				}
				else if (numero == 2) {
					Cliente c = new Cliente(2, "Marco Antonio");
					lista.add(c);
				}
				else
					System.out.println("Nao existe essa opcao");
			}
			if (opcao.equals("listar")) { 
				for (Pessoa p: lista) {
					System.out.println("CPF > " + p.getCpf());
					System.out.println("Nome > " + p.getNome());
				}
			}
	
		} while (!opcao.equals("sair"));
	}
}

Onde pode ser?
Era pra sair só 1 vez e não 2, como saiu na segunda vez (e partir daí fica assim).

16 Respostas

psandrelli

Coloca o mostrarOpcoes() antes do “do while”.

String opcao;
Controladora controladora = new Controladora();
controladora.mostrarOpcoes();
do {
Andre_Brito

Opz, acho que você não entendeu cara.
Ele deve aparecer dentro do while, mas só 1 vez. No caso, no meu quote, a primeira vez ele só aparece 1, na segunda em diante ele aparece 2 vezes.

andre.santos

Probleminha besta não, problemão! Só c/ debug p/ achar o erro.

Só qro ver se consigo explicar direito… rs :oops:

Acontece o seguinte:
Na primeira vez, qdo vc chama o reader.nextLine();, não há nenhuma linha (ou enter) para ser “lido”, aí funciona como deveria. Só que quando ele chega em numero = reader.nextInt(); você insere o integer (no caso “1”) e dá um <ENTER>, certo?

Neste momento o scanner lê o integer que você inseriou (mas não o enter) e executa o código, porém quando volta para o topo do while, o enter ainda não foi lido pelo scanner, então o reader.nextLine(); lê o enter (só que fornecendo uma string vazia) e executa o código novamente, como nenhum dos IF é satisfeito ele volta para o início e pára no reader.nextLine();.

Conseguiu entender?

Vc pode resolver da seguinte forma, ao invés de numero = reader.nextInt(); use:

System.out.print("Digite a sua opcao > "); numero = Integer.parseInt(reader.nextLine()); if (numero == 1) {.

Espero ter ajudado.
Abraços!

Gauss

Não entendo nada de programação procedural :smiley:

Andre_Brito

Nossa andre (nome bonito por sinal). Primeiramente eu quero agradecer.
Explicou bem ein? Sempre tive esse tipo de problema em C, quando o buffer estava cheio. Só não entendi uma coisa:

Mesmo eu apertando o ENTER ele não aceita ele? Digo… eu digito 1 e daí Enter (como você falou)… ele não deveria ler o enter também?
De uns tempos pra cá o scanner tem me dado alguns problemas… as vezes era porque não lia e agora isso…
Sobre seu código, você não acha que isso fica meio gambi? Não existe outra maneira de consertar isso? (não estou julgando nem nada…).

Abraço e valeu!

Gauss:
Também não gosto hehehe… as mains eu só faço pra teste mesmo… prefiro muito mais o BlueJ, mas quero começar a usar mais o vIM.

Abraço.

maior_abandonado

bom… gambi eu acho que não é não, mais java tem recursos de web e de ambiente grafico que não são assim dificeis de usar, então programa em batch só se for pra fica realmente rapido, e ai é masi aconselhavel um c++ (minha opinião).

o problema do ender é que ao da um nextInt() no q foi digitado, ele só vai ler algum numero inteiro, e enter vc consegue ler com o nextLine(), junto com o resto da linha ou de repente um System.getProperty ("line.separator")//acho que é isso, não lembro exatamente…

o que o andré falo ta certo em relação ao

System.out.print("Digite a sua opcao > ");   
numero = Integer.parseInt(reader.nextLine());   
if (numero == 1) {

mais eu acho que seria ainda mais legal vc bota otro do while ai pra garanti que o bokó do usuario vai digita um inteiro, exemplo:

System.out.print("Digite a sua opcao > ");
do{  
      boolean deuMerda=false;
      try{ 
           numero = Integer.parseInt(reader.nextLine());
       }catch(Exception e){  
           System.out.print("\n digite um numero inteiro por gentileza, digite novamente \n\n ");
           deuMerda=true;
       }
}while(deuMerda==true);
if (numero == 1) {
rolemberg

Só uma pergunta besta…pq vc nao usa switch case??? a programação fica mais legivel…assim acredito que vc consigara resolver esse problema mais facil…pois no dia a dia, geralmente se usa switch case para fazer menu…

Andre_Brito

Switch? Case? Achei que eram só pra inteiros… não consegui fazer pra cadastrar, listar, sair e excluir, mas tudo bem. Poderia usar ali no outro (onde realmente usa inteiro), mas ia dar na mesma… afinal, essa main é só pra testes mesmo… se fosse a main de verdade seria MUITO mais organizada.

maior_abandonado,

Tem risadas com seu post uahuhauha, sobre o usuário.
Bom, vou ignorar isso por enquanto, mas depois penso em fazer esses tratamentos…
Tentei usar o System.getProperty("\n"); mas veja…

controladora.mostrarOpcoes();
			
			opcao = reader.nextLine();
			System.getProperty("\n");
			opcao = opcao.toLowerCase();
			
			if (opcao.equals("cadastrar")) {
				int numero;
				System.out.println("1 - Funcionario");
				System.out.println("2 - Cliente");
				System.out.print("Digite a sua opcao > ");
				// Nao sei porque, mas e a solucao!
				numero = reader.nextInt();
				if (numero == 1) {
					Funcionario f = new Funcionario(1, "Joao da Si
...

Não funcionou… será que eu coloquei no lugar certo?
Eu entendo que o que o andré falou dá certo (até testei aqui), mas queria mais alguma solução… será que existe?

Abraços e MUITO obrigado pelas respostas.

Gauss

P/ q vc criou um objeto da sua propria classe? Recursão de classes? XD

Axei mto estranho, pq vc n usa um this.mostraOpçoes(); só?

ps: procure deixar as instruções como “if”, “while” e afins, fora do main em uma classe.

Andre_Brito

Vou repetir o que já falei: Essa main é só pra teste temporário. Ela não vai ser assim, pode ficar tranquilo que se você pegar o código ele vai estar bem organizado.

Gauss

Ainda vc não me disse o porquê de estar criando um objeto da sua própria classe… você já pensou em postar o código inteiro? (das outras classes)

Andre_Brito

Gauss,

Não entendo como isso resolveria meu problema. Pode citar algo que ajude?

Gauss

Não da pra postar suas outras classes também?

Você parece não entender o próprio código… como espera que te ajudemos?

Kassiane_Pretti

Só uma coisinha, o switch serve apenas para int e char.
E para comparar strings vc utiliza o equals msm, mas para evitar qualquer problema com a digitação tipo: sair != SAIR; vc pode utilizar equalsIgnoreCase , com ele: sair == SAIR.

maior_abandonado

bom…acho que vc não intendeu direito, eu não manjo absolutamente anda de properties, mais conforme o tingol me explico certa vez aqui nesse forum(e eu não me lembro se é exatamente isso), tem uns aplicativos que não reconhecem o enter assim automaticamente, o que eu tava com problema na epoca era o notepad, que quando eu dava \n em uma string e mandava grava ela num arquivo texto, aparecia quadradinho no texto e não pulava…

ele me explicou queo notepad não intendia \n e nesse caso eu teria que usar o System.getProperty ("line.separator") ; <-- no meu outro post o codigo fico com um rostinho em ) ;

juro que a imagem ali foi sem kerer…rs

e é System.getProperty ("line.separator") e não ("\n"); deve da diferença…

na epoca eu tinha criado uma classe log que gera um log texto de forma a ser reaproveitavel, pra mim usa ela daqui pra frente, ela recebe o endereço do arquivo, ve se ele existe, caso não o cria com um cabeçalho com a explicação também recebida pelo metodo, caso exista pula essa parte, e depois ela imprime na ultima linha do arquivo, o ultimo parametro recebido, uma string contendo o log que tem que ter nessa linha (podendo usar ela em qualquer aplicativo pois o aplicativo que geraria a informação do lgo e essa classe só o imprime no arquivo texto.)

o problema ai era pula a linha depois do final do arquivo, pq tava aparecendo quadradinho ao inves de pular a linha, ai eu concatenei o getproperties a string da saida, e funciono…

no seu caso é mais viavel mesmo ler a linha inteira e comparar do jeito que o andré falo (pro ser mais facil e funcionar normalmente), o getproperties seria util caso vc quisesse só ver se ali tem um enter, uma mudança de linha, o que é desnecessario pra vc…

caso vc queira da pra ler o inteiro pelo nextInt e depois ir passando até encontra o lineseparator mais não vale a pena, ai sim vc vai ter dor de cabeça (e seria um tanto lusitano)…

Andre_Brito

maior_abandonado,

Eu tentei usar o line.separator, mas também não deu certo.
Fiquei com a solução que o andré propôes memso :slight_smile:

Valeu pela ajuda.

Criado 9 de janeiro de 2008
Ultima resposta 11 de jan. de 2008
Respostas 16
Participantes 7