[RESOLVIDO] Uso da classe Scanner

12 respostas
rafael.espiritosanto

Olá!

Na descrição do método next() da classe Scanner, está o seguinte trecho:

No entanto, este método não serve para strings com mais de uma palavra (contendo espaços em branco). Tentei utilizar o método nextLine(), mas esse não está bloqueando a execução do aplicativo para que o usuário possa digitar os dados. O que pode ser feito para remediar este problema?

abraço!

12 Respostas

D

o nextLine ler toda a linha…
msm vc tendo espaços em branco entre palavras…
como vc esta fazeno?/

vlw

rafael.espiritosanto

Foi mal se ficou confuso

Segue parte do código
public class GeraArquivoConfiguracaoJabRef {
	final static String TABNAME = "customTabName_";
	final static String TABFIELD = "customTabFields_3";
	static int valor = 3;
	
	public static void main(String[] args) {
		int opcao = 0;
		Scanner scan = new Scanner(System.in);
		
		Vector<String> perguntas = new Vector<String>();
		Vector<String> criteriosInclusaoExclusao = new Vector<String>();
		Vector<String> criteriosAvaliacaoQualidade = new Vector<String>();
		Vector<String> criteriosHierarquizacao = new Vector<String>();
		
		do {
			System.out.println("Selecione a opção");
			System.out.println("1 - Adicionar Critério de Inclusão/Exclusão");
			System.out.println("2 - Adicionar Critério de Avaliação de Qualiadde");
			System.out.println("3 - Adicionar Critério de Hierarquização");
			System.out.println("4 - Adicionar Campo de Dados a Ser Extraído de Estudos Primários");
			System.out.println("5 - Gerar Arquivo de Preferências do JabRef");
			System.out.println("6 - Sair");
			
			try {
				opcao = scan.nextInt();
			} catch (InputMismatchException e) {
				System.out.println("opção inválida!");
				break;
			}
			
			switch (opcao) {
			case 1:
				adicionaCriterioInclusaoExclusao(scan, criteriosInclusaoExclusao);
				break;
			case 2:
				adicionaCriterioAvaliacaoQualidade(scan, criteriosAvaliacaoQualidade);
				break;
			case 3:
				adicionaCriterioHierarquizacao(scan, criteriosHierarquizacao);
				break;
			case 4:
				adicionaPergunta(scan, perguntas);
				break;
			case 5:
				try {
					geraArquivoPreferencia(perguntas, criteriosInclusaoExclusao, criteriosAvaliacaoQualidade, criteriosHierarquizacao);
				} catch (JDOMException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}
				break;
			case 6:
				System.out.println("Aplicativo Finalizado");
				break;
			default:
				System.out.println("Opção inválida");
				break;
			}
		} while (opcao != 6);
	}

	private static void adicionaCriterioHierarquizacao(Scanner scan,
			Vector<String> criteriosHierarquizacao) {
		System.out.println("Informe o critério");
		String pergunta = scan.nextLine();
		criteriosHierarquizacao.add(pergunta);
	}
D

especifique auql é o problema…
vlw

D

ahh sim…entendi o q vc quis dizer…
cria uma nova Scanner dentro do metodo…
assim…

public class GeraArquivoConfiguracaoJabRef {
	final static String TABNAME = "customTabName_";
	final static String TABFIELD = "customTabFields_3";
	static int valor = 3;
	
	public static void main(String[] args) {
		int opcao = 0;
		Scanner scan = new Scanner(System.in);
		
		Vector<String> perguntas = new Vector<String>();
		Vector<String> criteriosInclusaoExclusao = new Vector<String>();
		Vector<String> criteriosAvaliacaoQualidade = new Vector<String>();
		Vector<String> criteriosHierarquizacao = new Vector<String>();
		
		do {
			System.out.println("Selecione a opção");
			System.out.println("1 - Adicionar Critério de Inclusão/Exclusão");
			System.out.println("2 - Adicionar Critério de Avaliação de Qualiadde");
			System.out.println("3 - Adicionar Critério de Hierarquização");
			System.out.println("4 - Adicionar Campo de Dados a Ser Extraído de Estudos Primários");
			System.out.println("5 - Gerar Arquivo de Preferências do JabRef");
			System.out.println("6 - Sair");
			
			try {
				opcao = scan.nextInt();
			} catch (InputMismatchException e) {
				System.out.println("opção inválida!");
				break;
			}
			
			switch (opcao) {
			case 1:
				adicionaCriterioInclusaoExclusao(scan, criteriosInclusaoExclusao);
				break;
			case 2:
				adicionaCriterioAvaliacaoQualidade(scan, criteriosAvaliacaoQualidade);
				break;
			case 3:
				adicionaCriterioHierarquizacao(scan, criteriosHierarquizacao);
				break;
			case 4:
				adicionaPergunta(scan, perguntas);
				break;
			case 5:
				try {
					geraArquivoPreferencia(perguntas, criteriosInclusaoExclusao, criteriosAvaliacaoQualidade, criteriosHierarquizacao);
				} catch (JDOMException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}
				break;
			case 6:
				System.out.println("Aplicativo Finalizado");
				break;
			default:
				System.out.println("Opção inválida");
				break;
			}
		} while (opcao != 6);
	}

	private static void adicionaCriterioHierarquizacao(Scanner scan,
			Vector<String> criteriosHierarquizacao) {
                Scanner novaScan = new Scanner(System.in);
		System.out.println("Informe o critério");
		String pergunta = novaScan.nextLine();
		criteriosHierarquizacao.add(pergunta);
	}

testa essa ai…vlw

rafael.espiritosanto

O problema é que ao executar o código

opcao = scan.nextInt()

o aplicativo bloqueia o fluxo de execução até que eu forneça a opção. No entanto, o mesmo não acontece quando é executado o trecho

String pergunta = scan.nextLine(); Com isso o aplicativo segue no loop e as opções de escolha são novamente exibidas, sem que eu tenha a possibilidade de digitar o critério desejado (um exemplo de critério seria: O artigo está em inglês).

Se eu uso scan.next() ao invés de scan.nextLine(), o problema acima não ocorre. No entanto, o valor da variável pergunta vai ser somente a primeira palavra (no exemplo corresponderia a “O”), ou seja, o restante da linha vai ser descartado.

vlw

tnaires

Estranho… Fiz o mesmo teste aqui na minha máquina e o nextLine() ficou esperando minha entrada.
O que o método delimiter() da classe Scanner tá retornando?

rafael.espiritosanto

Estranho… a solução de criar um novo Scanner dentro do método funcionou, mas não sei dizer o por quê…

Eu usei o código System.out.println(scan.delimiter().pattern()); e o conteúdo retornado foi \p{javaWhitespace}+
Tentei “setar” o delimiter com o valor “\r” mas o aplicativo continuou em loop. Se usar “\n\r” o aplicativo fica travado eternamente e se uso apenas “\n” o aplicativo cai na exceção InputMismatchException por causa do método scan.nextInt()

vlw

FacaNaCaveira

Fala ai rafael.espiritosanto, nao sei se compreendi direito o seu problema, mas pelo o que percebi nao seria melhor criar um metodo so para fazer a leitura do parametro scan e outro metodo para o criteriosHierarquizacao?

adicionaCriterioHierarquizacao(scan, criteriosHierarquizacao)

Abração :!:
Max

rafael.espiritosanto

Olá Max!

Mas eu já não estou fazendo isto? Vê lá no código. Um amigo descobriu o problema. O erro estava no trecho

opcao = scan.nextInt();

O \n da linha do int que tava sendo pego como lixo!

Mudei para

opcao = Integer.parseInt(scan.nextLine());

e funcionou!

Valeu pela ajuda pessoal!

ViniGodoy

Ao ler do console, use somente o método nextLine().

Alguns professores tem ensinado o nextInt() e outros métodos similares, mas isso está errado.

Lembre-se a única terminação válida num terminal é o \n (ou \r\n, no caso do Windows), que o nextInt() não foi feito para capturar. Se você usar o nextInt() ele captura o inteiro e mantém o \n no buffer, que será lido no próximo nextLine(), o que gera depois os problemas que você vivenciou.

tnaires

ViniGodoy:
Ao ler do console, use somente o método nextLine().

Alguns professores tem ensinado o nextInt() e outros métodos similares, mas isso está errado.

Lembre-se a única terminação válida num terminal é o \n (ou \r\n no caso do Windows), que o nextInt() não foi feito para capturar. Se você usar o nextInt() ele captura o inteiro e mantém o \n no buffer, que será lido no próximo nextLine(), o que gera depois os problemas que você vivenciou.


Nossa Vini, matou a pau nessa explicação… Não sabia dessa particularidade!

ViniGodoy

rafael.espiritosanto:
Foi mal se ficou confuso

Segue parte do código

Agora que voltei nesse código depois de uns dias que vi. Você está usando Vector.

Recomendo fortemente que você troque pela classe ArrayList, que é o substituto do Vector. A Sun desaconselha o uso do Vector desde o Java 1.2, onde foi introduzida a Collections Framework.

Usar o ArrayList é muito similar a usar o Vector, veja:
http://www.guj.com.br/posts/list/74068.java#389435

Criado 15 de julho de 2010
Ultima resposta 21 de jul. de 2010
Respostas 12
Participantes 5