Я пытаюсь взять строковый ввод, который состоит из нескольких строк чисел, разделенных символами ',' и ';' ,
Пример:
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
Почему я получаю такой вывод?
Одна из проблем заключается в том, что 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();
...
}
}
Поскольку 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
он также заканчивает ввод на первой пустой строке при чтении с терминала.
hasNext()
при чтении файлов; может быть, вам нужна петля, контролируемая дозорным. Цикл, пока пользователь не введет -999 или некоторое число int, которое не должно быть частью введенных данных