Проверка правильности ввода с использованием java.util.Scanner

Я принимаю пользовательский ввод от System.in используя java.util.Scanner, Мне нужно проверить ввод для таких вещей, как:

  • Это должно быть неотрицательное число
  • Это должна быть буква алфавита
  • ... так далее

Какой лучший способ сделать это?

6 ответов

Обзор Scanner.hasNextXXX методы

java.util.Scanner имеет много hasNextXXX методы, которые могут быть использованы для проверки ввода. Вот краткий обзор всех из них:

  • hasNext() - есть ли вообще какой-нибудь токен?
  • hasNextLine() - у него есть другая строка ввода?
  • Для Java примитивов
    • 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,


Пример 1: проверка положительных значений

Вот простой пример использования 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's not a number!");
        sc.next(); // this is important!
    }
    number = sc.nextInt();
} while (number <= 0);
System.out.println("Thank you! Got " + number);

Вот пример сеанса:

Пожалуйста, введите положительное число!
5
Это не число!
-3
Пожалуйста, введите положительное число!
5
Спасибо! Получил 5

Обратите внимание, насколько проще Scanner.hasNextInt() использовать по сравнению с более многословным try/catchInteger.parseInt / NumberFormatException комбо. По контракту, Scanner гарантирует, что если это hasNextInt(), затем nextInt() мирно даст вам это int, и не будет бросать любой NumberFormatException / InputMismatchException / NoSuchElementException,

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


Пример 2: несколько hasNextXXX в том же духе

Обратите внимание, что приведенный выше фрагмент содержит sc.next() заявление для продвижения Scanner пока это hasNextInt(), Важно понимать, что ни один из hasNextXXX методы продвижения Scanner мимо любого входа! Вы обнаружите, что если вы пропустите эту строку из фрагмента, то это приведет к бесконечному циклу при неверном вводе!

Это имеет два последствия:

  • Если вам нужно пропустить "мусорный" ввод, который не сработает 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
ложный
(логическое) ложь
вздор
(Строка) бла
1,1
(двойной) 1,1
100000000000
(длинный) 100000000000
выход

Обратите внимание, что порядок испытаний имеет значение. Если ScannerhasNextInt() тогда это тоже hasNextLong(), но это не обязательно true наоборот. Чаще всего вы хотите провести более конкретный тест перед более общим тестом.


Пример 3: валидация гласных

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

Scanner sc = new Scanner(System.in);
System.out.println("Please enter a vowel, lowercase!");
while (!sc.hasNext("[aeiou]")) {
    System.out.println("That's not a vowel!");
    sc.next();
}
String vowel = sc.next();
System.out.println("Thank you! Got " + vowel);

Вот пример сеанса:

Пожалуйста, введите гласный, строчные буквы!
5
Это не гласная!
Z
Это не гласная!
е
Спасибо! Получил е

В регулярном выражении, как строковый литерал Java, шаблон "[aeiou]" это то, что называется "класс персонажа"; это соответствует любой из букв a, e, i, o, u, Обратите внимание, что сделать вышеуказанный тест-регистронезависимым тривиально: просто предоставьте такой шаблон регулярного выражения Scanner,

API ссылки

  • hasNext(String pattern) - возврат true если следующий токен соответствует шаблону, созданному из указанной строки.
  • java.util.regex.Pattern

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

Рекомендации


Пример 4: использование двух 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);
}

Вот пример сеанса:

Дайте мне кучу цифр в строке (или "выход")
3 4 5
Сумма 12
10 100 миллионов долларов
Сумма 110
чего ждать?
Сумма 0
выход

В дополнение к Scanner(String) конструктор, есть также Scanner(java.io.File) среди других.


Резюме

  • Scanner предоставляет богатый набор функций, таких как hasNextXXX методы проверки.
  • Правильное использование hasNextXXX/nextXXX в сочетании означает, что Scanner НИКОГДА не бросит InputMismatchException / NoSuchElementException,
  • Всегда помни это hasNextXXX не продвигает Scanner мимо любого входа.
  • Не стесняйтесь создавать несколько Scanner если необходимо. Два простых Scanner часто лучше, чем один слишком сложный Scanner,
  • Наконец, даже если у вас нет планов использовать расширенные функции регулярных выражений, помните, какие методы основаны на регулярных выражениях, а какие нет. любой Scanner метод, который принимает String pattern Аргумент основан на регулярных выражениях.
    • Совет: простой способ превратить любой String в буквальном смысле является Pattern.quote Это.

Вот минималистичный способ сделать это.

System.out.print("Please enter an integer: ");
while(!scan.hasNextInt()) scan.next();
int demoInt = scan.nextInt();

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

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;
}

Одна идея:

try {
    int i = Integer.parseInt(myString);
    if (i < 0) {
        // Error, negative input
    }
} catch (NumberFormatException e) {
    // Error, not a number.
}

В библиотеке commons-lang также есть класс CharUtils, который предоставляет методы isAsciiNumeric() проверить, что символ является числом, и isAsciiAlpha() чтобы проверить, что символ является буквой...

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

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);

Если вы анализируете строковые данные из консоли или чего-либо подобного, лучше всего использовать регулярные выражения. Подробнее об этом читайте здесь: http://java.sun.com/developer/technicalArticles/releases/1.4regex/

В противном случае, чтобы проанализировать int из строки, попробуйте Integer.parseInt (string). Если строка не является числом, вы получите исключение. В противном случае вы можете выполнить проверку этого значения, чтобы убедиться, что оно не отрицательное.

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;
   }
}

Удачи!

Другие вопросы по тегам