java validation java.util.scanner

Validar entrada usando java.util.Scanner



validation (6)

Descripción general de los métodos de Scanner.hasNextXXX

java.util.Scanner tiene muchos métodos hasNextXXX que se pueden usar para validar la entrada. Aquí hay una breve descripción de todos ellos:

Scanner es capaz de más, habilitado por el hecho de que está basado en expresiones regulares. Una característica importante es useDelimiter(String pattern) , que le permite definir qué patrón separa sus tokens. También hay métodos de find y skip que ignoran los delimitadores.

La siguiente discusión mantendrá la expresión regular tan simple como sea posible, por lo que el foco permanece en el Scanner .

Ejemplo 1: Validación de resultados positivos

Aquí hay un ejemplo simple de usar hasNextInt() para validar el int positivo de la entrada.

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

Aquí hay una sesión de ejemplo:

Por favor ingrese un número positivo!
cinco
¡Eso no es un número!
-3
Por favor ingrese un número positivo!
5
¡Gracias! Tengo 5

Tenga en cuenta qué tan fácil es usar Scanner.hasNextInt() en comparación con el más detallado NumberFormatException try/catch Integer.parseInt / NumberFormatException combo. Por contrato, un Scanner garantiza que si tiene hasNextInt() , nextInt() le dará pacíficamente esa int , y no arrojará ninguna NumberFormatException / InputMismatchException / NoSuchElementException .

Preguntas relacionadas

Ejemplo 2: Múltiple hasNextXXX en el mismo token

Tenga en cuenta que el fragmento de arriba contiene una sc.next() para avanzar en el Scanner hasta que hasNextInt() . ¡Es importante darse cuenta de que ninguno de los métodos de hasNextXXX avanzar el Scanner allá de cualquier entrada! Encontrarás que si omites esta línea del fragmento, ¡entraría en un ciclo infinito en una entrada no válida!

Esto tiene dos consecuencias:

  • Si necesita omitir la entrada "basura" que falla su prueba de hasNextXXX , entonces necesita avanzar el Scanner una forma u otra (por ejemplo, next() , nextLine() , skip , etc.).
  • Si uno hasNextXXX prueba hasNextXXX falla, ¡ aún puede probar si tal vez tiene hasNextYYY !

Aquí hay un ejemplo de realizar múltiples pruebas de 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() ); }

Aquí hay una sesión de ejemplo:

5
(int) 5
falso
(booleano) falso
paja
(Cuerda) bla
1.1
(doble) 1.1
100000000000
(largo) 100000000000
salida

Tenga en cuenta que el orden de las pruebas es importante. Si un Scanner hasNextInt() , también hasNextLong() , pero no es necesariamente true al revés. En la mayoría de los casos, querrá hacer la prueba más específica antes de la prueba más general.

Ejemplo 3: Validar vocales

Scanner tiene muchas funciones avanzadas compatibles con expresiones regulares. Aquí hay un ejemplo de usarlo para validar vocales.

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

Aquí hay una sesión de ejemplo:

Por favor, introduzca una vocal, minúscula!
5
¡Eso no es una vocal!
z
¡Eso no es una vocal!
mi
¡Gracias! Tengo e

En regex, como un literal de cadena Java, el patrón "[aeiou]" es lo que se llama una "clase de caracteres"; coincide con cualquiera de las letras a , e , i , o , u . Tenga en cuenta que es trivial hacer que la prueba anterior no distinga entre mayúsculas y minúsculas: simplemente proporcione dicho patrón de expresiones regulares al Scanner .

Enlaces API

Preguntas relacionadas

Referencias

Ejemplo 4: uso de dos Scanner a la vez

Algunas veces necesita escanear línea por línea, con múltiples tokens en una línea. La forma más fácil de lograr esto es usar dos Scanner , donde el segundo Scanner toma la nextLine() del primer Scanner como entrada. Aquí hay un ejemplo:

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

Aquí hay una sesión de ejemplo:

Dame un montón de números en una línea (o ''salir'')
3 4 5
Suma es 12
10 100 millones de dólares
Suma es 110
¿esperar lo?
Suma es 0
salida

Además del constructor Scanner(String) , también hay Scanner(java.io.File) entre otros.

Resumen

  • Scanner proporciona un hasNextXXX conjunto de características, como los métodos hasNextXXX para la validación.
  • El uso adecuado de hasNextXXX/nextXXX en combinación significa que un Scanner NUNCA lanzará una InputMismatchException / NoSuchElementException .
  • Recuerde siempre que hasNextXXX no hace avanzar el Scanner allá de cualquier entrada.
  • No sea tímido para crear un Scanner múltiple si es necesario. Dos Scanner simples a menudo son mejores que un Scanner demasiado complejo.
  • Finalmente, incluso si no tiene planes de utilizar las funciones avanzadas de expresiones regulares, tenga en cuenta qué métodos están basados ​​en expresiones regulares y cuáles no. Cualquier método de Scanner que tome un argumento de String pattern está basado en expresiones regulares.
    • Sugerencia : una manera fácil de convertir cualquier String en un patrón literal es Pattern.quote it.

Estoy tomando la entrada del usuario de System.in usando java.util.Scanner . Necesito validar la entrada para cosas como:

  • Debe ser un número no negativo
  • Debe ser una letra alfabética
  • ... etc

¿Cuál es la mejor manera de hacer esto?


Aquí hay una forma minimalista de hacerlo.

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


Lo que he intentado es que primero tome la entrada de enteros y compruebe si es negativo o no, si es negativo, entonces, de nuevo, tome la entrada

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

Aquí, primero debe tomar la entrada de caracteres y verificar si el usuario le dio carácter o no, si no más que tomar la entrada de caracteres

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


Para comprobar Cadenas de letras puede usar expresiones regulares, por ejemplo:

someString.matches("[A-F]");

Para comprobar los números y detener el bloqueo del programa, tengo una clase bastante simple que puede encontrar a continuación, donde puede definir el rango de valores que desea. Here

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


Si está analizando datos de cadena desde la consola o similar, la mejor manera es usar expresiones regulares. Lea más al respecto aquí: http://java.sun.com/developer/technicalArticles/releases/1.4regex/

De lo contrario, para analizar un int de una cadena, intente Integer.parseInt(string) . Si la cadena no es un número, obtendrá una excepción. De otro modo, puede realizar sus controles sobre ese valor para asegurarse de que no sea negativo.

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!"); }

Para obtener una cadena de sólo caracteres, probablemente sería mejor que recorriera cada carácter buscando los dígitos, utilizando, por ejemplo, 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; } }

¡Buena suerte!


Una idea:

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

También hay, en la biblioteca commons-lang , la clase CharUtils que proporciona los métodos isAsciiNumeric() para verificar que un personaje sea un número, y es isAsciiAlpha() para verificar que el personaje sea una letra ...