Guest id194 Posted March 16, 2008 Report Share Posted March 16, 2008 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? Link to comment Share on other sites More sharing options...
magician Posted March 16, 2008 Report Share Posted March 16, 2008 Ao invés desse while sem grande logica porque não usas os hasNextLine da classe Scanner? Tipo while( input.hasNextLine() ){ ..... } I haven’t lost my mind; it’s backed up on DVD somewhere! Link to comment Share on other sites More sharing options...
Guest id194 Posted March 16, 2008 Report Share Posted March 16, 2008 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. Link to comment Share on other sites More sharing options...
magician Posted March 16, 2008 Report Share Posted March 16, 2008 Porque nao usas o Console para capturar o input ? Tenho usado em recurso ao System.in http://java.sun.com/javase/6/docs/api/java/io/Console.html I haven’t lost my mind; it’s backed up on DVD somewhere! Link to comment Share on other sites More sharing options...
Guest id194 Posted March 16, 2008 Report Share Posted March 16, 2008 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... Link to comment Share on other sites More sharing options...
Betovsky Posted March 16, 2008 Report Share Posted March 16, 2008 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. "Give a man a fish and he will eat for a day; Teach a man to fish and he will eat for a lifetime. The moral? READ THE MANUAL !" Sign on a computer system consultant's desk Link to comment Share on other sites More sharing options...
Rui Carlos Posted March 16, 2008 Report Share Posted March 16, 2008 Estás a fechar o input... Basta retirares o input.close() e fica o problema resolvido. Rui Carlos Gonçalves Link to comment Share on other sites More sharing options...
magician Posted March 16, 2008 Report Share Posted March 16, 2008 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. I haven’t lost my mind; it’s backed up on DVD somewhere! Link to comment Share on other sites More sharing options...
Rui Carlos Posted March 16, 2008 Report Share Posted March 16, 2008 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. [...'] Rui Carlos Gonçalves Link to comment Share on other sites More sharing options...
Guest id194 Posted March 16, 2008 Report Share Posted March 16, 2008 @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... Link to comment Share on other sites More sharing options...
Rui Carlos Posted March 17, 2008 Report Share Posted March 17, 2008 @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. Rui Carlos Gonçalves Link to comment Share on other sites More sharing options...
Guest id194 Posted March 17, 2008 Report Share Posted March 17, 2008 Eu li o teu post, mas não sei ao certo o que significa... Link to comment Share on other sites More sharing options...
Rui Carlos Posted March 17, 2008 Report Share Posted March 17, 2008 Quando fechas um Scanner, fechas também a stream fonte (o System.in, neste caso), se ele poder ser fechado (o que é o caso). Rui Carlos Gonçalves Link to comment Share on other sites More sharing options...
Guest id194 Posted March 17, 2008 Report Share Posted March 17, 2008 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... Link to comment Share on other sites More sharing options...
Rui Carlos Posted March 17, 2008 Report Share Posted March 17, 2008 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). Rui Carlos Gonçalves Link to comment Share on other sites More sharing options...
Guest id194 Posted March 17, 2008 Report Share Posted March 17, 2008 Então o que é que recomendas? Apenas remover a linha input.close() e fica bom? Link to comment Share on other sites More sharing options...
Betovsky Posted March 17, 2008 Report Share Posted March 17, 2008 @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. "Give a man a fish and he will eat for a day; Teach a man to fish and he will eat for a lifetime. The moral? READ THE MANUAL !" Sign on a computer system consultant's desk Link to comment Share on other sites More sharing options...
Rui Carlos Posted March 17, 2008 Report Share Posted March 17, 2008 Então o que é que recomendas? Apenas remover a linha input.close() e fica bom? Penso que sim... Rui Carlos Gonçalves Link to comment Share on other sites More sharing options...
Guest id194 Posted March 17, 2008 Report Share Posted March 17, 2008 Ok. Obrigado a todos. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now