2013-03-13 21 views
5

Ogni volta che si esegue questa operazione, la funzione chooseCave() funziona correttamente con in.nextInt(). Quando ho scelto la grotta, i messaggi pop-up ad intervalli di 2 secondi, e poi, non appena si arriva passato che parte, mi dà l'errore:Eccezione nella discussione "main" java.util.NoSuchElementException

Exception in thread "main" java.util.NoSuchElementException: No line found 
    at java.util.Scanner.nextLine(Unknown Source) 
    at Dragon.main(Dragon.java:81) 

Ho provato hasNextLine() e hasNextInt(), e quando ho utilizzare while hasNextLine() nel metodo main, ottengo più errori. Quando uso while hasNextInt() nel metodo chooseCave(), non accetta il mio input.

Quando uso if hasNextInt() nel metodo chooseCave(), che non accetta il mio ingresso per la stringa playAgain, e va dritto in un altro gioco, ma poi i rendimenti hasNextInt() booleane false e Spam "Quale grotta ..." infinitamente .

Ho passato le segnalazioni di errore e Java-docs e Stack Overflow con problemi simili. Per favore aiuto.

import java.util.Scanner; 
public class Dragon { 

public static void displayIntro() { 
    System.out.println("You are in a land full of dragons. In front of you, "); 
    System.out.println("You see two caves. In one cave, the dragon is friendly"); 
    System.out.println("and will share his treasure with you. The other dragon"); 
    System.out.println("is greedy and hungry, and will eat you on sight"); 
    System.out.println(' '); 
} 

public static int chooseCave() { 
    Scanner in = new Scanner(System.in); 
    int cave = 0; 
    while (cave != 1 && cave != 2) { 
     System.out.println("Which cave will you go into? (1 or 2)"); 

     cave = in.nextInt(); 

    } 
    in.close(); 
    return cave; 
} 

public static void checkCave(int chosenCave) { 
    System.out.println("You approach the cave..."); 
    try 
     { 
     // Sleep at least n milliseconds. 
     // 1 millisecond = 1/1000 of a second. 
     Thread.sleep(2000); 
     } 
    catch (InterruptedException e) 
     { 
     System.out.println("awakened prematurely"); 
     } 
    System.out.println("It is dark and spooky..."); 
    try 
     { 
     // Sleep at least n milliseconds. 
     // 1 millisecond = 1/1000 of a second. 
     Thread.sleep(2000); 
     } 
    catch (InterruptedException e) 
     { 
     System.out.println("awakened prematurely"); 
     } 
    System.out.println("A large dragon jumps out in front of you! He opens his jaws and..."); 
    try 
     { 
     // Sleep at least n milliseconds. 
     // 1 millisecond = 1/1000 of a second. 
     Thread.sleep(2000); 
     } 
    catch (InterruptedException e) 
     { 
     System.out.println("awakened prematurely"); 
     } 

    double friendlyCave = Math.ceil(Math.random() * 2); 

    if (chosenCave == friendlyCave) { 
     System.out.println("Gives you his treasure!"); 
    } 
    else { 
     System.out.println("Gobbles you down in one bite!"); 
    } 



} 
public static void main(String[] args) { 
    Scanner inner = new Scanner(System.in); 
    String playAgain = "yes"; 
    boolean play = true; 
    while (play) { 
     displayIntro(); 
     int caveNumber = chooseCave(); 
     checkCave(caveNumber); 
     System.out.println("Do you want to play again? (yes or no)"); 
     playAgain = inner.nextLine(); 
     if (playAgain == "yes") { 
      play = true; 
     } 
     else { 
      play = false; 
     } 
    } 
    inner.close(); 

} 

} 

risposta

8

si chiude la seconda Scanner che chiude il sottostante InputStream, quindi il primo Scanner non può leggere dal medesimo InputStream ea NoSuchElementException risultati.

La soluzione: per le app console, utilizzare un singolo Scanner da leggere da System.in.

A parte: Come già detto, tenere presente che Scanner#nextInt non consuma caratteri di nuova riga. Assicurarsi che questi vengano consumati prima di tentare di chiamare di nuovo nextLine utilizzando Scanner#newLine().

See: Do not create multiple buffered wrappers on a single InputStream

+0

+1, ho dimenticato di menzionare i diversi scanner con un problema di input. – syb0rg

+0

Grazie a te e syb0rg. Ho appena dovuto eliminare il metodo con lo scanner e posizionare l'equivalente nel metodo principale. Funziona! Il primo successo in un nuovo linguaggio di programmazione ... sembra davvero buono. :) –

5

Il metodo nextInt() lascia il simbolo \n (fine linea) e viene prelevato immediatamente nextLine(), saltando il successivo ingresso. Che cosa si vuole fare è utilizzare nextLine() per tutto, e analizzare in un secondo momento:

String nextIntString = keyboard.nextLine(); //get the number as a single line 
int nextInt = Integer.parseInt(nextIntString); //convert the string to an int 

Questo è di gran lunga il modo più semplice per evitare problemi - do not mix vostri metodi "Avanti". Utilizzare solo nextLine() e quindi analizzare le parole int o successive.


Inoltre, assicurarsi di utilizzare un solo Scanner se il vostro utilizza un solo terminale per l'ingresso. Questa potrebbe essere un'altra ragione per l'eccezione.


Ultima nota: confronta un String con la funzione .equals(), non l'operatore ==.

if (playAgain == "yes"); // Causes problems 
if (playAgain.equals("yes")); // Works every time 
+0

Grazie! Vorrei avere abbastanza punti da qui per invogliarti. Ho aggiustato quello che hai detto, e comunque non ha funzionato ... ma la buona notizia è che, una volta tolto lo scanner dal metodo, sono riuscito a mettere tutto nel metodo principale e ha funzionato bene. Aiutato anche con l'inizializzazione del numero. Grazie ancora! :) –

1

Reimeus è giusto, si vede questo a causa della in.close nel chooseCave(). Inoltre, questo è sbagliato.

if (playAgain == "yes") { 
     play = true; 
} 

È necessario utilizzare equazioni anziché "==".

if (playAgain.equals("yes")) { 
     play = true; 
} 
+0

Concordato, ma non la causa dell'errore. Potrebbe tuttavia causare problemi in seguito ... – syb0rg

0

semplicemente non chiudere in

rimuovere in.close() dal codice.

+0

Questo duplica la risposta accettata, ma con una qualità molto inferiore. – JasonMArcher

+0

Anche io stavo affrontando lo stesso problema .. Dopo aver cercato molto su internet e infine rimosso in.close() dal mio codice ha funzionato per me. Ecco perché ho risposto a questo. –

+0

Questa risposta era già stata data e con una spiegazione molto migliore. –

-1

Ho ricevuto lo stesso errore e nessuna di queste soluzioni ha funzionato. Prova a controllare la versione di Java installata sul tuo PC.

Ha funzionato per me su Java 1.8.

Problemi correlati