Я беру ввод пользователя с System.in
с помощью java.util.Scanner
. Мне нужно проверить вход для таких вещей, как:
- Это должно быть неотрицательное число
- Это должно быть алфавитная буква
- ... и т.д.
Какой лучший способ сделать это?
Я беру ввод пользователя с System.in
с помощью java.util.Scanner
. Мне нужно проверить вход для таких вещей, как:
Какой лучший способ сделать это?
Scanner.hasNextXXX
java.util.Scanner
имеет много методов hasNextXXX
, которые могут использоваться для проверки ввода. Вот краткий обзор всех из них:
hasNext()
- у него есть любой токен вообще?hasNextLine()
- есть ли еще одна строка ввода?hasNextInt()
- у него есть токен, который можно разобрать в int
?hasNextDouble()
, hasNextFloat()
, hasNextByte()
, hasNextShort()
, hasNextLong()
и hasNextBoolean()
hasNextBigInteger()
и hasNextBigDecimal()
hasNext(String pattern)
hasNext(Pattern pattern)
- это Pattern.compile
перегрузка Scanner
способен к большему, включенному тем, что он основан на регулярном выражении. Важной особенностью является useDelimiter(String pattern)
, которая позволяет определить, какой шаблон разделяет ваши токены. Существуют также методы find
и skip
, которые игнорируют разделители.
Следующее обсуждение будет поддерживать регулярное выражение как можно более простым, поэтому фокус остается на Scanner
.
Вот простой пример использования hasNextInt()
для проверки положительного int
на входе.
Scanner sc = new Scanner(System.in);
int number;
do {
System.out.println("Please enter a positive number!");
while (!sc.hasNextInt()) {
System.out.println("That not a number!");
sc.next(); // this is important!
}
number = sc.nextInt();
} while (number <= 0);
System.out.println("Thank you! Got " + number);
Вот пример сеанса:
Введите положительное число!
пять
Это не число!
-3
Введите положительное число!
5
Спасибо! Получил 5
Заметьте, насколько проще Scanner.hasNextInt()
использовать по сравнению с более подробными try/catch
Integer.parseInt
/NumberFormatException
комбо. По контракту a Scanner
гарантирует, что если он hasNextInt()
, то nextInt()
мирно предоставит вам int
и не будет бросать никаких NumberFormatException
/InputMismatchException
/NoSuchElementException
.
hasNextXXX
на одном и том же токенеОбратите внимание, что вышеприведенный фрагмент содержит инструкцию sc.next()
для продвижения Scanner
до тех пор, пока не будет hasNextInt()
. Важно понимать, что ни один из методов hasNextXXX
не продвигает Scanner
мимо любого ввода!. Вы обнаружите, что если вы опустите это line из фрагмента, затем он перейдет в бесконечный цикл на недопустимом вводе!
Это имеет два следствия:
hasNextXXX
, вам необходимо заранее продвинуть Scanner
(например, next()
, nextLine()
, skip
и т.д.)).hasNextXXX
завершился с ошибкой, вы все равно можете проверить, возможно ли это hasNextYYY
!Здесь приведен пример выполнения нескольких тестов hasNextXXX
.
Scanner sc = new Scanner(System.in);
while (!sc.hasNext("exit")) {
System.out.println(
sc.hasNextInt() ? "(int) " + sc.nextInt() :
sc.hasNextLong() ? "(long) " + sc.nextLong() :
sc.hasNextDouble() ? "(double) " + sc.nextDouble() :
sc.hasNextBoolean() ? "(boolean) " + sc.nextBoolean() :
"(String) " + sc.next()
);
}
Вот пример сеанса:
5
(int) 5
ложь
(boolean) false
бла
(String) blah
1.1
(двойной) 1.1
100000000000
(длинный) 100000000000
выход
Обратите внимание, что порядок испытаний имеет значение. Если a Scanner
hasNextInt()
, то это также hasNextLong()
, но это не обязательно true
наоборот. Чаще всего вы хотите сделать более конкретный тест перед более общим тестом.
Scanner
имеет множество расширенных функций, поддерживаемых регулярными выражениями. Вот пример его использования для проверки гласных.
Scanner sc = new Scanner(System.in);
System.out.println("Please enter a vowel, lowercase!");
while (!sc.hasNext("[aeiou]")) {
System.out.println("That not a vowel!");
sc.next();
}
String vowel = sc.next();
System.out.println("Thank you! Got " + vowel);
Вот пример сеанса:
Введите гласный, в нижнем регистре!
5
Это не гласный!
г
Это не гласный!
е
Спасибо! Получил e
В regex, как строковый литерал Java, шаблон "[aeiou]"
- это так называемый "класс символов"; он соответствует любой из букв a
, e
, i
, o
, u
. Обратите внимание, что это тривиально, чтобы сделать вышеупомянутый тест нечувствительным к регистру: просто укажите такой шаблон регулярного выражения на Scanner
.
hasNext(String pattern)
- возвращает true
, если следующий токен совпадает с шаблоном, построенным из указанной строки.java.util.regex.Pattern
Scanner
сразуИногда вам нужно сканировать строки за строкой, с несколькими токенами на линии. Самый простой способ сделать это - использовать два Scanner
, где второй Scanner
принимает nextLine()
из первого Scanner
в качестве входного. Вот пример:
Scanner sc = new Scanner(System.in);
System.out.println("Give me a bunch of numbers in a line (or 'exit')");
while (!sc.hasNext("exit")) {
Scanner lineSc = new Scanner(sc.nextLine());
int sum = 0;
while (lineSc.hasNextInt()) {
sum += lineSc.nextInt();
}
System.out.println("Sum is " + sum);
}
Вот пример сеанса:
Дайте мне кучу чисел в строке (или "exit" )
3 4 5
Сумма составляет 12
10 100 млн. Долларов
Сумма составляет 110
ждать, что? Сумма 0
Выход
В дополнение к Scanner(String)
constructor, также Scanner(java.io.File)
и др.
Scanner
предоставляет богатый набор функций, таких как hasNextXXX
методы для проверки.hasNextXXX/nextXXX
в комбинации означает, что Scanner
будет НИКОГДА не вывести InputMismatchException
/NoSuchElementException
.hasNextXXX
не продвигает Scanner
мимо любого ввода.Scanner
, если это необходимо. Два простых Scanner
часто лучше, чем один сложный Scanner
.Scanner
, который принимает аргумент String pattern
, основан на регулярном выражении.
String
в литеральный шаблон - Pattern.quote
it.Для проверки строк для букв вы можете использовать регулярные выражения, например:
someString.matches("[A-F]");
Для проверки номеров и остановки сбой программы, у меня есть довольно простой класс, который вы можете найти ниже, где вы можете определить диапазон значений, которые вы хотите. Здесь
public int readInt(String prompt, int min, int max)
{
Scanner scan = new Scanner(System.in);
int number = 0;
//Run once and loop until the input is within the specified range.
do
{
//Print users message.
System.out.printf("\n%s > ", prompt);
//Prevent string input crashing the program.
while (!scan.hasNextInt())
{
System.out.printf("Input doesn't match specifications. Try again.");
System.out.printf("\n%s > ", prompt);
scan.next();
}
//Set the number.
number = scan.nextInt();
//If the number is outside range print an error message.
if (number < min || number > max)
System.out.printf("Input doesn't match specifications. Try again.");
} while (number < min || number > max);
return number;
}
Здесь минималистский способ сделать это.
System.out.print("Please enter an integer: ");
while(!scan.hasNextInt()) scan.next();
int demoInt = scan.nextInt();
Одна идея:
try {
int i = Integer.parseInt(myString);
if (i < 0) {
// Error, negative input
}
} catch (NumberFormatException e) {
// Error, not a number.
}
В commons-lang библиотека CharUtils класс, который предоставляет методы isAsciiNumeric()
, чтобы проверить, что символ является числом, и isAsciiAlpha()
, чтобы проверить, что символ является буквой...
Если вы разбираете строковые данные с консоли или аналогичные, лучший способ - использовать регулярные выражения. Подробнее об этом читайте здесь: http://java.sun.com/developer/technicalArticles/releases/1.4regex/
В противном случае, чтобы проанализировать int из строки, попробуйте Integer.parseInt(строка). Если строка не является числом, вы получите исключение. Кроме того, вы можете выполнить свои проверки на это значение, чтобы убедиться, что оно не является отрицательным.
String input;
int number;
try
{
number = Integer.parseInt(input);
if(number > 0)
{
System.out.println("You positive number is " + number);
}
} catch (NumberFormatException ex)
{
System.out.println("That is not a positive number!");
}
Чтобы получить строку только для символов, вам, вероятно, будет лучше зацикливаться на каждом символе, проверяющем цифры, используя, например, Character.isLetter(char).
String input
for(int i = 0; i<input.length(); i++)
{
if(!Character.isLetter(input.charAt(i)))
{
System.out.println("This string does not contain only letters!");
break;
}
}
Удачи!
что я пробовал, так это то, что сначала я взял целочисленный ввод и проверил, является ли его отрицательным или нет, если его отрицательный снова принимает вход
Scanner s=new Scanner(System.in);
int a=s.nextInt();
while(a<0)
{
System.out.println("please provide non negative integer input ");
a=s.nextInt();
}
System.out.println("the non negative integer input is "+a);
Здесь вам нужно сначала взять ввод символа и проверить, дал ли пользователь символ или нет, если нет, а затем снова введите символ
char ch = s.findInLine(".").charAt(0);
while(!Charcter.isLetter(ch))
{
System.out.println("please provide a character input ");
ch=s.findInLine(".").charAt(0);
}
System.out.println("the character input is "+ch);