Как выйти из цикла while в java с методом сканера hasNext в качестве условия?

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

Проблема в том, что программа никогда не заканчивается, и, насколько я понимаю, она застряла внутри цикла while. Может ли кто-нибудь помочь мне немного? Заранее спасибо.

import java.util.Scanner;

public class Test{
   public static void main(String args[]){
      System.out.print("Enter your sentence: ");
      Scanner sc = new Scanner (System.in);

      while (sc.hasNext() == true ) {
        String s1 = sc.next();
        System.out.println(s1);
      }

      System.out.println("The loop has been ended"); // This somehow never get printed.
   }
}

person davidx1    schedule 07.05.2012    source источник
comment
(оффтоп) Принято писать просто while (sc.hasNext()), а не while (sc.hasNext() == true). hasNext() уже возвращает вам логическое значение.   -  person Greg Kopff    schedule 08.05.2012


Ответы (9)


Вы продолжаете получать новую новую строку и продолжаете цикл, если он не пуст. Просто вставьте элемент управления в цикл для строки выхода.

while(!s1.equals("exit") && sc.hasNext()) {
    // operate
}

Если вы хотите объявить строку внутри цикла и не выполнять операции в теле цикла, если строка "выход":

while(sc.hasNext()) {
    String s1 = sc.next();
    if(s1.equals("exit")) {
        break;
    }
    //operate
}
person İsmet Alkan    schedule 07.05.2012
comment
Это хорошо, но только если вы объявляете String вне цикла (что может быть не очень желательно) и если вы хотите выполнить тело цикла, даже когда вы получаете выход String, так как вы проверяете это условие только ПОСЛЕ выполнения цикла. тело, которое почти всегда не то, что хочется. - person Renato; 08.05.2012

Scanner будет продолжать чтение, пока не найдет условие «конец файла».

Поскольку вы читаете из stdin, это будет либо при отправке символа EOF (обычно ^d в Unix), либо в конце файла, если вы используете перенаправление в стиле <.

person Alnitak    schedule 07.05.2012

Когда вы используете сканер, как упоминал Alnitak, вы получаете «false» для hasNext() только тогда, когда у вас есть символ EOF, в основном... Вы не можете легко отправить символ EOF с помощью клавиатуры, поэтому в подобных ситуациях это обычное дело чтобы иметь специальный символ или слово, которое вы можете отправить, чтобы остановить выполнение, например:

String s1 = sc.next();
if (s1.equals("exit")) {
    break;
}

Перерыв выведет вас из петли.

person Renato    schedule 07.05.2012
comment
Вы не можете легко отправить символ EOF с помощью клавиатуры — обычно это делает Ctrl+D в Linux/Unix/Mac или Ctrl+Z в Windows. - person trutheality; 08.05.2012
comment
Спасибо, но знание ОС обычно плохо сочетается с Java... отсюда и комментарий. - person Renato; 08.05.2012

Ваше условие правильное (хотя вы должны убрать == true). Происходит то, что сканер будет продолжать работать, пока не достигнет конца ввода. Попробуйте Ctrl+D или направьте ввод из файла (java myclass < input.txt).

person Kevin    schedule 07.05.2012

это не работает, потому что вы не запрограммировали отказоустойчивость в коде. java видит, что сканер все еще может собирать входные данные, пока есть входные данные, которые нужно собрать, и, если это возможно, пока это правда, он продолжает это делать. иметь тест сканера, чтобы увидеть, подходит ли определенное слово, например, EXIT, но вы также можете зациклить его определенное количество раз, например, десять или около того. но наиболее эффективный подход — спросить пользователя вашей программы, сколько строк он хочет ввести, и хотя количество вводимых им строк меньше числа, которое они ввели, программа должна выполняться. дополнительная опция может быть, если они наберут EXIT, когда увидят, что им нужно меньше пробелов, чем они вставили, и не хотят заполнять следующие ячейки только пробелами. и вы можете сделать так, чтобы программа спрашивала, хотят ли они ввести больше данных, на случай, если они поймут, что им нужно ввести больше данных в компьютер. программу было бы довольно просто сделать, потому что существует множество способов, которыми вы могли бы это сделать. не стесняйтесь спрашивать меня об этих способах, хотя мне не хватает места. XD

person Thomas    schedule 17.02.2013

Если вы не хотите использовать для этого символ EOF, вы можете использовать StringTokenizer :

import java.util.*;
public class Test{
   public static void main(){
      Scanner sc = new Scanner (System.in);
      System.out.print("Enter your sentence: ");
      String s=sc.nextLine();
      StringTokenizer st=new StringTokenizer(s," ");//" " is the delimiter here.
      while (st.hasMoreTokens() ) {
        String s1 = st.nextToken();
        System.out.println(s1);
      }

      System.out.println("The loop has been ended");
   }
}
person Zia Ansari    schedule 17.10.2014

У меня была та же проблема, и я решил ее, прочитав всю строку из консоли с помощью одного объекта сканера, а затем проанализировав полученную строку с помощью второго объекта сканера.

Scanner console = new Scanner(System.in);
System.out.println("Enter input here:");
String inputLine = console.nextLine();

Scanner input = new Scanner(inputLine);
List<String> arg = new ArrayList<>();

while (input.hasNext()) {
    arg.add(input.next().toLowerCase());
}
person Skandalos    schedule 05.11.2018

Вы можете просто использовать один из зависящих от системы индикаторов конца файла ( d для Unix/Linux/Ubuntu, z для Windows), чтобы сделать оператор while ложным. Это должно выбить вас из колеи. :)

person TOLU    schedule 30.09.2014

Измените цикл while, как показано ниже. Объявите s1 как строку s1; один раз вне цикла. Чтобы завершить цикл, просто нажмите ctrl+z.

  while (sc.hasNext())
  {    
    s1 = sc.next();
    System.out.println(s1);
    System.out.print("Enter your sentence: ");
  }
person Sisir Ray    schedule 19.02.2013