• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

Nazgulled

Excepção - java.util.NoSuchElementException: No line found ???

19 mensagens neste tópico

Boas,

Tenho o seguinte código:

import java.util.InputMismatchException;
import java.util.Scanner;

public class Input {

public static String readString() {
	return _readString(null, null);
}

public static String readString(String title) {
	return _readString(title, null);
}

public static String readString(String title, String error) {
	return _readString(title, error);
}

private static String _readString(String title, String error) {
	Scanner input = new Scanner(System.in);
	boolean loop = true;
	String str = null;

	while(loop) {
		try {
			if(title != null) {
				System.out.print(title);
			}

			str = input.nextLine();
			loop = false;
		} catch(InputMismatchException e) {
			if(error != null) {
				System.out.println(error);
			}
		}
	}

	input.close();

	return str;
}

}

public class Program {

public static void main(String[] args) {
	String a;

	a = Input.readString("VALOR: ");
	System.out.println(a);

	a = Input.readString("\nVALOR: ");
	System.out.println(a);
}

}

E dá-me o seguinte output:

VALOR: Olá Mundo!
Olá Mundo!

VALOR: Exception in thread "main" java.util.NoSuchElementException: No line found
at java.util.Scanner.nextLine(Scanner.java:1516)
at Input._readString(Input.java:29)
at Input.readString(Input.java:11)
at Program.main(Program.java:21)

Ou seja, o primeiro valor é lido sem problemas, mas o segundo não. Quando Input.readString() é invocada pela segunda vez a excepção que está no título deste tópico, ocorre na linha str = input.nextLine();.

Alguém me consegue explicar porquê que isto está a acontecer?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Ao invés desse while sem grande logica porque não usas os hasNextLine da classe Scanner?

Tipo

while( input.hasNextLine() ){
    .....
}

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Porque a ideia não é essa e o while precisa de lá estar.

Mas isso é irrelevante para o problema, não é o while que esta a causar a excepção e é isso que eu preciso de resolver.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Desculpa la e espero que não leves a mal, mas eu não quero soluções para contornar o problema e/ou soluções diferentes.

Quero resolver o problema que tenho, usar o máximo do código que tenho sem que dê aquela excepção que para mim não faz sentido nenhum estar dar. Também não percebo quase nada de Java, mas por isso que é que estou aqui...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Bem, assim de repente penso em 2 motivos.

1 - Na segunda vez não estás a terminar a linha com uma mudança de linha. Ou seja, ele fica a espera de um terminar de linha (normalmente '\n'), e percorre o Input todo sem encontrar tal. Isto poderá estar a acontecer se estiveres a mandar o input por redirecionamento pro programa, etc.

2 - Não tenho a certeza disto, mas também é uma possibilidade. Ao fazeres Close() na primeira vez, para além de estar a fechar o Scanner estás também a fechar a stream de input. Portanto na próxima vez que vais tentar ler ela irá estar fechada. Acho isto pouco provável, já que se tal fosse a causa, provavelmente a excepção seria outra.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Estás a fechar o input... Basta retirares o input.close() e fica o problema resolvido.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Estás a fechar o input... Basta retirares o input.close() e fica o problema resolvido.

Ele tá a fechar o Scanner e não o in e como o método é chamado de novo o Scanner também é aberto de novo.

O Scanner é mais utilizado para a leitura continua dai ter sugerido o Console que é mesmo para este tipo de interacções  tipo o scanf do C.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Ele tá a fechar o Scanner e não o in e como o método é chamado de novo o Scanner também é aberto de novo.

O Scanner é mais utilizado para a leitura continua dai ter sugerido o Console que é mesmo para este tipo de interacções  tipo o scanf do C.

[...]

When a Scanner is closed, it will close its input source if the source implements the Closeable interface.

[...']

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

@Betovsky

Relativamente ao ponto #1, sinceramente, não percebi...

Quanto ao resto, de facto, remover o input.close() resolveu o problema, mas não percebo a lógica... Primeiro, não entendo o mal de chamar input.close() porque como o magician disse, quando o método é chamada, o Scanner é criado, portanto não consigo entender porquê que remover o input.close() resolve o problema. E segundo, não é suposto fecharmos o Scanner depois de não precisarmos mais dele? Sim, eu vou precisar dele na leitura seguinte, mas por isso é que tenho o new Scanner() no inicio do método.

Não entendo...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

@Betovsky

Relativamente ao ponto #1, sinceramente, não percebi...

Quanto ao resto, de facto, remover o input.close() resolveu o problema, mas não percebo a lógica... Primeiro, não entendo o mal de chamar input.close() porque como o magician disse, quando o método é chamada, o Scanner é criado, portanto não consigo entender porquê que remover o input.close() resolve o problema. E segundo, não é suposto fecharmos o Scanner depois de não precisarmos mais dele? Sim, eu vou precisar dele na leitura seguinte, mas por isso é que tenho o new Scanner() no inicio do método.

Não entendo...

Lê o meu post anterior. Na documentação do Java está lá explícita esta situação.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Quando fechas um Scanner, fechas também a stream fonte (o System.in, neste caso), se ele poder ser fechado (o que é o caso).

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Ya, já percebi, tive a ler com mais atenção... Obrigado.

Mas não há nenhuma volta a dar evitando remover o input.close()? Não há forma de dizer "fecha só o scanner e deixa a Strem.in aberta". Isso era o ideal, penso eu de que...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Se queres continuar a usar a stream fonte, a única coisa que poderias ter que fazer é eliminar o objecto (coisa que em Java não é necessário), a operação de fechar o Scanner por si só não tem propriamente interesse (pois não é ele que precisa de ser fechado).

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Então o que é que recomendas? Apenas remover a linha input.close() e fica bom?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

@Betovsky

Relativamente ao ponto #1, sinceramente, não percebi...

Tipo, se estás a fazer nextLine(), estás a mandar ler até encontrar uma mudança de linha. Agora se estiveres a usar um ficheiro de input tipo isto:

welelele ....
tralalala ...

Iria funcionar bem, mas se usasses antes este:

welelele ....
tralalala ...

Já iria funcionar mal, a diferença é que o de cima acaba com uma mudança de linha o de baixo não.

Claro que refiro a quando está a mandar um ficheiro de input para efectuar testes. Tipo: ./meuPrograma < fichInputTeste.txt

Pelo teclado tal não acontece.

Mas pelos vistos é o problema nº 2 e então não te precisas de preocupar com isto.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Então o que é que recomendas? Apenas remover a linha input.close() e fica bom?

Penso que sim...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora