Java Scanner во время цикла

1

Я пытаюсь взять строковый ввод, который состоит из нескольких строк чисел, разделенных символами ',' и ';' ,

Пример:

1,2;3,4;5,6;
9,8;7,6;
0,1;
;

Код:

ArrayList<Integer> alist = new ArrayList<>();
        String delims = ";|\\,";
        int i = 0;
        Scanner input = new Scanner(System.in);
        input.useDelimiter(delims);
        while (input.hasNext()) {
            alist.add(i, input.nextInt());
            System.out.print(i + ' ');
            System.out.print(alist.get(i) + '\n');
            i++;
        }
        System.out.print('x');

Когда я запускаю это в eclipse:

1,2;3,4;5,6;    ( <= what i typed in console)
321133123413351436153716    ( <= output)                

Я бы ожидал чего-то большего:

0 1
1 2
2 3
3 4
4 5 
5 6
x

Почему я получаю такой вывод?

  • 1
    я использовал метод сканеров hasNext() при чтении файлов; может быть, вам нужна петля, контролируемая дозорным. Цикл, пока пользователь не введет -999 или некоторое число int, которое не должно быть частью введенных данных
Теги:
arraylist
while-loop
java.util.scanner
system.in

2 ответа

1
Лучший ответ

Одна из проблем заключается в том, что System.in - это в основном бесконечный поток: hasNext всегда возвращает true, если пользователь не вводит специальную команду, которая его закрывает.

Поэтому вам нужно, чтобы пользователь вводил то, что говорит вам, что они сделаны. Например:

while(input.hasNext()) {
    System.out.print("Enter an integer or 'end' to finish: ");
    String next = input.next();
    if("end".equalsIgnoreCase(next)) {
        break;
    }

    int theInt = Integer.parseInt(next);
    ...

Для вашей программы у вас может быть вход, который вы пытаетесь разобрать с помощью специального символа, такого как 1,2;3,4;5,6;end или 1,2;3,4;5,6;# который вы проверяете для.

И в этих строках:

System.out.print(i + ' ');
System.out.print(alist.get(i) + '\n');

Похоже, вы пытаетесь выполнить конкатенацию String но поскольку char является числовым, он вместо этого выполняет добавление. Вот почему вы получаете безумный выход. Поэтому вам нужно использовать String вместо char:

System.out.print(i + " ");
System.out.print(alist.get(i) + "\n");

Или просто:

System.out.println(i + " " + alist.get(i));

Изменить комментарий.

Например, вы можете вытащить вход с помощью следующей nextLine из Scanner с разделителем по умолчанию, а затем создать второй Scanner для сканирования строки:

Scanner sysIn = new Scanner(System.in);
while(sysIn.hasNextLine()) {
    String nextLine = sysIn.nextLine();
    if(nextLine.isEmpty()) {
        break;
    }

    Scanner lineIn = new Scanner(nextLine);
    lineIn.useDelimiter(";|\\,");

    while(lineIn.hasNextInt()) {
        int nextInt = lineIn.nextInt();
        ...
    }
}
  • 0
    о человек, это всегда мелочи, переход на двойную речь полностью исправил вывод :) спасибо
  • 0
    Как бы я использовал следующую пустую строку, чтобы закончить поток?
0

Поскольку Radiodef уже ответил на вашу фактическую проблему (" вместо '), вот несколько указателей, которые, на мой взгляд, могут быть полезны для вас (это скорее комментарий, чем ответ, но слишком длинный для фактического комментария):

Когда вы используете сканер, попробуйте выполнить hasNextX функции hasNextX вызова nextX. Т.е. в вашем случае используйте hasNextInt и nextInt. Это делает гораздо менее вероятным, что вы получите исключение из неожиданного ввода, а также упростите ввод данных, просто набрав еще один разделитель.

Сканеры useDelimiter call возвращают сканер, поэтому его можно связать, как часть инициализации сканера. Т.е. вы можете просто написать:

Scanner input = new Scanner(System.in).useDelimiter(";|\\,");

Когда вы добавляете в конец ArrayList, вам не нужно (и обычно не следует) указывать индекс.

int я = 0, i++ - пример учебника цикла for. Просто потому, что ваш тестовый оператор не связан с i это не значит, что вы не должны использовать цикл for.

Ваш код, с указанными выше адресами, будет выглядеть следующим образом:

ArrayList<Integer> alist = new ArrayList<>();
Scanner input = new Scanner(System.in).useDelimiter(";|\\,");
for (int i = 0; input.hasNextInt(); i++) {
    alist.add(input.nextInt());
    System.out.println(i + " " + alist.get(i));
}
System.out.println('x');

Изменение: просто пришлось упомянуть один из моих любимых разделителей для сканера, так как он здесь подходит:

Scanner input = new Scanner(System.in).useDelimiter("\\D");

Это сделает сканер над просто цифрами, разделяя все, что не является числом. В сочетании с hasNextInt он также заканчивает ввод на первой пустой строке при чтении с терминала.

  • 0
    «используйте hasNextInt [...], чтобы упростить завершение ввода, просто набрав что-либо, кроме числа». Это не сработает, на самом деле сканер просто пропустит не-int и попытается сканировать вперед (он снова запросит) ) вместо возврата ложного.
  • 0
    Вы правы, спасибо, я перепутал \\ D и его разделитель. Используя hasNextInt, вы должны завершить ввод разделителем. Обновление, чтобы исправить это.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню