2014-07-20 5 views
-3

Итак, проблема с этим кодом заключается в том, что если он итерации по циклу более одного раза, закрытие сканера приводит к тому, что код пренебрегает сканированием для дальнейшего ввода пользователем. Я понимаю, что проблема должна быть внутренней в классе Scanner, но есть ли у кого-нибудь способ закрыть сканер безопаснее? (Это может помочь скопировать код и попробовать ввести «55» или «j», например, если вы не осознаете проблему, которую я сейчас имею).Java.util.Scanner, выпуск с закрытием

public static void main(String[] args){ 
    int numCom = 0, count = 0; 
    boolean valid = false; 

    do{ 
     Scanner num = new Scanner(System.in); 
     try{ 
      if(count == 0){ 
       System.out.println("Okay, how many adversaries would you like to be put up against? (between 1-8)"); 
       count++; 
      }else{ 
       System.out.println("Error!\nPlease enter a number between 1-8."); 
      } 
      numCom = num.nextInt(); 
     }catch(Exception e){} 
     if(numCom < 9 && numCom > 0){ 
      valid = true; 
     } 
     num.close(); 
    }while(!valid); 
}//main() 
+0

Вы комментировали ответы на все вопросы, кроме моего. Что-то не так с этим? – Boann

+0

Извините, я на самом деле не был на этом сайте некоторое время (недавно был плавный парусный спорт). Я ушел от попытки закрыть Scanners вообще для таких вещей, поскольку он также закрывает входной поток (System.in для этого случая). Если есть возможность снова открыть поток, это будет хорошо. –

+0

Я уже ответил на все это ... – Boann

ответ

0

Создайте и закройте сканер вне цикла. Как это:

public static void main(String[] args) { 
     int numCom = 0, count = 0; 
     boolean valid = false; 
     Scanner num = new Scanner(System.in); 

     do { 
      try { 
       if (count == 0) { 
        System.out.println("Okay, how many adversaries would you like to be put up against? (between 1-8)"); 
        count++; 
       } else { 
        System.out.println("Error!\nPlease enter a number between 1-8."); 
       } 
       numCom = num.nextInt(); 
      } catch (Exception e) {} 
      if (numCom < 9 && numCom > 0) { 
       valid = true; 
      } 
     } while (!valid); 
     num.close(); 
    } //main() 
+0

Нехорошо, попробуйте, но введите значение, которое заставляет цикл проходить через несколько раз.Это был мой первый инстинкт, но он даже не работает правильно, если вы не закрываете сканер, попробуйте его. –

+0

Вы пытались сделать функцию кода вместо того, чтобы иметь его в своем главном? – simeg

+0

Да, я просто копировал/вставлял это в темп-класс; в моей полной программе это отдельная функция. –

0

Try This: Java 7+ http://ideone.com/dxtXmz

public static void main(String[] args){ 
    int numCom = 0, count = 0; 
    boolean valid = false; 
     try (Scanner num = new Scanner(System.in)) { 
      do{ 
       try{ 
        if(count == 0){ 
         System.out.println("Okay, how many adversaries would you like to be put up against? (between 1-8)"); 
         count++; 
        }else{ 
         System.out.println("Error!\nPlease enter a number between 1-8."); 
        } 
        numCom = num.nextInt(); 
       }catch(Exception e){} 
       if(numCom < 9 && numCom > 0){ 
        valid = true; 
       } 
      }while(!valid); 
     } 
}//main() 

ИЛИ

Try This: http://ideone.com/LaN6kF

public static void main(String[] args){ 
int numCom = 0, count = 0; 
boolean valid = false; 

    Scanner num = new Scanner(System.in); 
do{ 
    try{ 
     if(count == 0){ 
      System.out.println("Okay, how many adversaries would you like to be put up against? (between 1-8)"); 
      count++; 
     }else{ 
      System.out.println("Error!\nPlease enter a number between 1-8."); 
     } 
     numCom = num.nextInt(); 
    }catch(Exception e){} 
    if(numCom < 9 && numCom > 0){ 
     valid = true; 
    } 
}while(!valid); 

    num.close(); 
}//main() 

В основном ресурс: сканер: выделяется только один раз и повторно использовать. , и когда это не требуется, его закрытие.

+0

Да, попробовал это тоже уже по сути и не повезло, к сожалению .. –

+0

все работает просто отлично: http://ideone.com/dxtXmz –

+0

http://ideone.com/LaN6kF –

0

Если вам нужно обрабатывать строки, а также, попробуйте это один:http://ideone.com/f7IMwD

public static void main(String[] args) { 
     int numCom = 0, count = 0; 
     boolean valid = false; 
     try (Scanner num = new Scanner(System.in)) { 
      do { 
       try { 
        if (count == 0) { 
         System.out.println("Okay, how many adversaries would you like to be put up against? (between 1-8)"); 
         count++; 
        } else { 
         System.out.println("Error!\nPlease enter a number between 1-8."); 
        } 
        String line = num.nextLine(); 
        numCom = Integer.parseInt(line); 
        if (numCom < 9 && numCom > 0) { 
         valid = true; 
        } 
       } catch (NumberFormatException e) { 
        valid = false; 
       } 

      } while (!valid); 
     } 
    }//main() 
+0

Да, похоже, что у него действительно есть потенциал. Хотелось бы, чтобы вы знали, что это не так утомительно? Редактировать: это работает отлично, вы могли бы продвигать вас, если бы я мог! –

+0

Оставшиеся блоки 'catch' пустые и надеющиеся' exceptions' будут позабочены * автоматически * - могут показаться менее утомительными *, но не то, что должно быть сделано. –

+0

О, я даже не говорил о блоке catch, просто нужно создать экземпляр новой строки, а затем использовать метод parseInt(). Вы все равно можете оставить блок захвата пустым без каких-либо последствий! –

0

Что вам нужно, чтобы убедиться, что только сканер закрыт, а не в System.in. Вызов scanner.close() в свою очередь вызывает закрытие источника, который вы предоставляете в конструкторе (System.in) в этом случае. У вас есть два варианта. Более элегантный один будет использовать http://commons.apache.org/proper/commons-io/javadocs/api-release/org/apache/commons/io/input/CloseShieldInputStream.html

Scanner num = new Scanner(new CloseShieldInputStream(System.in)); 

чистое решение ява будет

public class Scan { 
private static final class MyShieldedSystemIn extends InputStream { 
    @Override 
    public int read(byte[] b) throws IOException { 
     return System.in.read(b); 
    } 

    @Override 
    public int read(byte[] b, int off, int len) throws IOException { 
     return System.in.read(b, off, len); 
    } 

    @Override 
    public void close() throws IOException { 
     // do nothing 
     System.out.println("ignoring call to close()"); 
    } 

    @Override 
    public int read() throws IOException { 
     return System.in.read(); 
    } 
} 
final static InputStream SSI = new MyShieldedSystemIn(); 
public static void main(String[] args){ 
    int numCom = 0, count = 0; 
    boolean valid = false; 


    do{ 
     Scanner num = new Scanner(SSI); 
     try{ 
      if(count == 0){ 
       System.out.println("Okay, how many adversaries would you like to be put up against? (between 1-8)"); 
       count++; 
      }else{ 
       System.out.println("Error!\nPlease enter a number between 1-8."); 
      } 
      numCom = num.nextInt(); 
     }catch(Exception e){} 
     if(numCom < 9 && numCom > 0){ 
      valid = true; 
     } 
     num.close(); 
    }while(!valid); 
}//main() 

}

+0

Это солидный совет, но поскольку он, к сожалению, не имеет аналога в java, он просто больше входит в мой код в конце день. –

+0

Честно говоря, просто чтобы добавить одну вещь, это был также самый хорошо информированный пост здесь, так хорошо на вас, мужчина (или женщина, idk)! :) –

+0

Это много ненужного кода. Вам не нужно *** закрыть сканер. – Boann

0

При закрытии Scanner, он закроет свой источник входного сигнала, который в этот случай System.in. Как только вы закрыли System.in, вы больше не можете читать ввод. Не закрывайте Scanner. У него нет никаких ресурсов, которые необходимо закрыть, если вы не хотите закрыть источник ввода, который в этом случае у вас нет. Если вы удалите вызов num.close();, ваш код будет работать правильно.

Редактировать: Тем не менее, вы делаете тяжелую работу. Длина вашего кода может быть вдвое без потери функциональности:

int numAdversaries; 
System.out.println("Okay, how many adversaries would you like to be put up against? (between 1-8)"); 
for (;;) { 
    try { 
     numAdversaries = new Scanner(System.in).nextInt(); 
     if (numAdversaries >= 1 && numAdversaries <= 8) break; 
    } catch (Exception e) {} 
    System.out.println("Error!\nPlease enter a number between 1-8."); 
} 
Смежные вопросы