2014-10-19 54 views
2

下面的代碼在我按Ctrl + Z 後給我錯誤java.util.NoSuchElementException來指示用戶輸入已完成。看起來好像它不知道如何結束一個方法而不會搞亂另一個掃描器對象。 我嘗試了hasNext方法,並且我以無限循環結束了,無論哪種方式都不起作用。作爲這項任務的要求,我需要能夠告訴用戶根據操作系統使用Ctrl + Z或D.此外,我需要能夠從文本文件中讀取並將最終的樹保存爲文本文件,請幫助。如何避免java.util.NoSuchElementException

/* sample input: 
     CSCI3320 
     project 
     personal 
     1 HW1 
     1 HW2 
     1 2 MSS.java 
     2 p1.java 

     */ 

    import java.util.Scanner; 
    import java.util.StringTokenizer; 

    public class Directory { 

     private static TreeNode root = new TreeNode("/", null, null); 

     public static void main(String[] args) { 
      userMenu(); 
      System.out.println("The directory is displayed as follows:"); 
      root.listAll(0); 

     } 

     private static void userMenu(){   //Displays users menu 
      Scanner userInput = new Scanner(System.in);//Scanner option 
      int option = 0; 
      do{ //I believe the problem is here since I am not using userInput.Next() 
       System.out.println("\n 1. add files from user inputs "); 
       System.out.println("\n 2. display the whole directory "); 
       System.out.println("\n 3. display the size of directory "); 
       System.out.println("\n 0. exit"); 
       System.out.println("\n Please give a selection [0-3]: "); 
       option = userInput.nextInt(); 
        switch(option){ 
         case 1: addFileFromUser(); 
           break; 
         case 2: System.out.println("The directory is displayed as follows:"); 
           root.listAll(0); 
           break; 
         case 3: System.out.printf("The size of the directory is %d.\n", root.size()); 
           break; 
         default: 
           break; 
         } 
      }while(option !=0); 
      userInput.close(); 

     } 
     private static void addFileFromUser() { 

      System.out.println("To terminate inp1ut, type the correct end-of-file indicator "); 
      System.out.println("when you are prompted to enter input."); 
      System.out.println("On UNIX/Linux/Mac OS X type <ctrl> d"); 
      System.out.println("On Windows type <ctrl> z"); 
      Scanner input = new Scanner(System.in); 

       while (input.hasNext()) { //hasNext being used Crtl Z is required to break 
        addFileIntoDirectory(input); // out of the loop. 
       } 
       input.close(); 
     } 


     private static void addFileIntoDirectory(Scanner input) { 

      String line = input.nextLine(); 
      if (line.trim().equals("")) return; 

      StringTokenizer tokens = new StringTokenizer(line); 

      int n = tokens.countTokens() - 1; 

      TreeNode p = root; 
      while (n > 0 && p.isDirectory()) { 

       int a = Integer.valueOf(tokens.nextToken()); 
       p = p.getFirstChild(); 

       while (a > 1 && p != null) { 
        p = p.getNextSibling(); 
        a--; 
       } 
       n--; 
      } 

      String name = tokens.nextToken(); 

      TreeNode newNode = new TreeNode(name, null, null); 
      if (p.getFirstChild() == null) { 
       p.setFirstChild(newNode); 
      } 
      else { 
       p = p.getFirstChild(); 
       while (p.getNextSibling() != null) { 
        p = p.getNextSibling(); 
       } 
       p.setNextSibling(newNode); 
      } 

     } 


     private static class TreeNode { 

      private String element; 
      private TreeNode firstChild; 
      private TreeNode nextSibling; 

      public TreeNode(String e, TreeNode f, TreeNode s) { 
       setElement(e); 
       setFirstChild(f); 
       setNextSibling(s); 
      } 


      public void listAll(int i) { 

       for (int k = 0; k < i; k++) { 
        System.out.print('\t'); 
       } 

       System.out.println(getElement()); 

       if (isDirectory()) { 
        TreeNode t = getFirstChild(); 

        while (t != null) { 

         t.listAll(i+1); 
         t = t.getNextSibling(); 
        } 

       } 
      } 


      public int size() { 

       int s = 1; 

       if (isDirectory()) { 
        TreeNode t = getFirstChild(); 

        while (t != null) { 
         s += t.size(); 
         t = t.getNextSibling(); 
        } 
       } 

       return s; 
      } 


      public void setElement(String e) { 
       element = e; 
      } 


      public String getElement() { 
       return element; 
      } 


      public boolean isDirectory() { 
       return getFirstChild() != null; 
      } 

      public void setFirstChild(TreeNode f) { 
       firstChild = f; 
      }  

      public TreeNode getFirstChild() { 
       return firstChild; 
      } 

      public void setNextSibling(TreeNode s) { 
       nextSibling = s; 
      }  

      public TreeNode getNextSibling() { 
       return nextSibling; 
      } 


     } 



    } 

異常詳細信息:

/*Exception in thread "main" java.util.NoSuchElementException 
      at java.util.Scanner.throwFor(Scanner.java:907) 
      at java.util.Scanner.next(Scanner.java:1530) 
      at java.util.Scanner.nextInt(Scanner.java:2160) 
      at java.util.Scanner.nextInt(Scanner.java:2119) 
      at Directory.userMenu(Directory.java:36) 
      at Directory.main(Directory.java:21)*/ 

回答

0

你的問題是這樣的一行:

option = userInput.nextInt(); //line 24 

如果你讀的Javadoc,你會發現nextInt()方法可以拋出一個NoSuchElementException如果輸入用盡了。換句話說,沒有下一個整數。爲什麼在你的代碼中發生這種情況?由於第一次迭代完成後(在外部while循環中),此行將處於循環中,因此您的初始輸入選擇已被佔用。由於這是一項功課,我不打算編寫代碼。但是,如果刪除循環,則至少可以運行一次。一旦你嘗試循環,它就會中斷。所以我會給你這些提示:

  1. 將do/while更改爲while循環。
  2. 在循環之外提示用戶一次。
  3. 重新創建提示並重新捕獲循環內的用戶輸入。

例如,下面的代碼可以用作外部循環的基礎。

import java.util.Scanner; 

public class GuessNumberGame { 

    public static void main(String[] args) { 
     Scanner input = new Scanner(System.in); 
     System.out.println("Guess the secret number: (Hint: the secret number is 1)"); 
     int guess = input.nextInt(); 

     while (guess != 1) { 
      System.out.println("Wrong guess. Try again: "); 
      guess = input.nextInt(); 
     } 
     System.out.println("Success"); 
     input.close(); 
    } 
} 

這個原因是因爲我不重複使用相同的耗盡的掃描儀輸入對象來獲取下一個整數。在你的例子中,初始輸入是在循環內部。第二次,該輸入已被消耗。按照這種模式,你應該能夠完成你的任務。祝你好運!