2016-03-18 4 views
0

Я знаю, что это много раз задавалось в StackOverflow, но я пробовал много разных решений, и никто из них не работал. Поэтому я решил спросить сообщество о том, что делать. Вот соответствующий фрагмент из моего кода.Хотя цикл с условием .hasNext работает бесконечно

public class Calculator 
{ 
    public static void main(String[]args) 
    { 
    ArrayList<String> inputStorage = new ArrayList<String>(); 
    Scanner input = new Scanner(System.in); 
    String rawInput; 
    boolean mainLoop = true; 

    String exitInput; 
    String mainMenuInput; 

    while(mainLoop == true) 
    { 
     mainMenuInput = input.nextLine() 
     switch(mainMenuInput) 
     { 
      case "Expression": 
       System.out.println("Type an expression"); 
       while(input.hasNext) 
       { 
        rawInput = input.next(); 
        inputStorage.add(rawInput); 
       } 
       break; 

      case "Equation": 
       System.out.println("Type an equation"); 
       while(input.hasNext) 
       { 
        rawInput = input.next(); 
        inputStorage.add(rawInput); 
       } 
       break; 
      case "exit": 
       System.out.println("Are you sure you want to exit") 
       exitInput = input.nextLine(); 
       switch(exitInput) 
       { 
       case "yes": 
       case "Yes": 
       mainLoop = false; 

       case "no": 
       case "No": 
       break; 

       default: 
       System.out.println("That was not an option") 
       break; 
       } 
      default: 
       System.out.println("That was not an option"); 
       break; 

     } 
    } 

Обратите внимание, что это только часть моего кода, который принимает входные данные с консоли без лишних включений. У меня есть другие настройки, которые требуют, чтобы код находился в этом формате.

Вот список того, что я пытался и не работал:

  • заменить input.hasNext() с input.hasNextLine()
  • заменить input.hasNext() с входным сигналом. следующий()! = NULL
  • делает условие выхода, если input.next = нуль
  • делает условие выхода, если input.next() = "\ п"
  • делает условие выхода, если input.next() = «\ r "

Вот список вещей, которые не будут работать для остальной части моего кода:

  • BufferedReader (и все методы и аспекты его)
  • заменить input.next() с входом. nextLine()

С учетом сказанного, я видел способ сделать это, выполнив условие выхода на основе значения ASKII символа newLine. Единственная проблема заключается в том, что я не нашел хорошего способа реализации значений символов ASKII в java-коде (или, по крайней мере, ни один из них, который бы работал с моим кодом), и для его реализации мне нужно было бы знать, как использует класс Scanner символ следующей линии. Но это всего лишь одно предлагаемое решение, и я уверен, что у кого-то есть лучший способ прекратить входной цикл, как это, когда нажата клавиша ввода.

Спасибо за ваше время.

ответ

0

Поскольку вашей Scanner манипуляционной открыта потока (System.in) он не может быть уверен, что этот поток не в середине создания и отправок Чем больше данных, что означает, что он не может возвращать лжи, пока

  • такого потока будут закрыты
  • мы получим данные, представляющие конец потока.

Из-за этого

while(input.hasNext()){ 
    ... 
} 

плохая идея, потому что вы заблокированы hasNext() пока вы не получите правильные данные (или Стрим будут закрыты).

Правильное решение зависит от вашего сценария.Если вы знаете, сколько чисел вы хотите читать просто использовать

for (int i = 0; i < N; i++){ 
    ... 
    rawInput = input.next(); 
    ... 
} 

В сценарии, в которых вы хотите обрабатывать токены только из одной линии, которую вы могли бы сначала прочитать эту строку, а затем разметить его с отдельным сканером

Scanner lineScanner = new Scanner(input.nextLine()); 
while(lineScanner.hasNext()){ 
    rawInput = lineScanner.next(); 
    inputStorage.add(rawInput); 
} 
+0

Нет. Я действительно об этом думал, но я не знаю, сколько цифр я буду читать раньше времени. Кроме того, входное хранилище должно содержать любой ввод, а не только цифры. Спасибо за вашу помощь. –

+0

Вам нужно как-то узнать, где находится конец данных, которые вы хотите прочитать. Обычно это либо предопределенная сумма (даже на основе более раннего ввода пользователя), либо какой-то особый символ (некоторое слово остановки, например «выход» или «-1») или даже разделитель строк - в последнем случае вам нужно будет использовать 'nextLine' вместо 'next' в главном сканере, потому что' next' видит разделители строк как пробелы, которые являются протекторами как разделители между токенами. – Pshemo

+0

Я думал о том, что пользователь вводит каждый вход с помощью «;», но не было бы возможности сказать, не было ли у них этого. Что касается функции readline, я должен иметь возможность различать токены и обрабатывать каждый из них как число, команду (+, -, *, x, /, ^, =) или переменную (математический вид, а не java) Мне также нужно обработать их в соответствии с тем, что означают маркеры до и после. Если вы не знаете способ разделить строку, созданную функцией readline, на свои жетоны, я не могу ее использовать. –

8

Вы никогда не устанавливаете mainLoop в false в конце. Вы действительно не нужно вложенные в то время как петли тоже, только одна из которых hasNext

+0

Я сказал, что это было только соответствующий фрагмент моего кода, необходимого, чтобы задать вопрос. mainLoop его цикл вокруг всей программы, потому что у меня есть главное меню, настроенное в нем. Код, который я вам предоставил, приведен в случае с оператором switch в главном меню. mainLoop имеет свои собственные условия выхода, к которым он обращается из главного меню, которое у меня установлено (не включено в этот код) –

+1

Ну, на основе фрагмента mainLoop вызывает бесконечный цикл. Не могли бы вы разместить больше своего кода? – Logan

+0

Извините, я новичок в StackOverflow, но я только что сделал. –

0

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

BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in)); 
String line; 
while((line=stdIn.readLine()) !=null && line.length()!=0){ 

} 
Смежные вопросы