Today I had an exam question in which I was asked for the following restrictions for a code that was requested by keyboard:
- It must have 9 characters, of which:
- The first has to be a number
- The second has to be a script
- The next 7 remaining characters have to be numbers
The code is requested three times, stored and displayed at each iteration
In the exam I did not know how to do it, and now at home I have done it in the following way that I think works:
public class RestringirEntradaTeclado {
public static void main(String[] args){
//instanciamos la clase Scanner para pedir el código
Scanner teclado = new Scanner(System.in);
//creamos un string para recoger dicho código
String codigo;
//creamos dos contadores, para el bucle del pedido y de los caracteres
int contador = 0, pedido = 1;
//creamos un ArrayList para almacenar los códigos
ArrayList<String> catalogo = new ArrayList<String>();
//mientras haya menos de tres pedidos, repetir
while (pedido <= 3){
//pedimos el código
System.out.println("Introduzca el código: ");
//recogemos el código en la variable
codigo = teclado.nextLine();
//creamos un array de caracteres
char[] miChar = new char[codigo.length()];
//pasamos el código recogido del teclado al array de caracteres
miChar = codigo.toCharArray();
//tomamos el primer caracter del array de caracteres y los convertimos a entero
int n1 = Character.getNumericValue(miChar[0]);
//efectuamos la primera evaluación de si el código tiene 9 caracteres
if (codigo.length() == 9){
//segunda evaluación, el primer carácter es un número ?
if ((n1 >= 0) && (n1 <= 9)){
//tercera evaluación, el segundo carácter es un guión ?
if (miChar[1] == '-'){
//creamos un bucle para evaluar los 7 caracteres restantes
for (int i = 2; i < 9; i++){
//en cada iteración del bucle, convertimos el carácter del array de caracteres en número
int n2 = Character.getNumericValue(miChar[i]);
//En la cuatra evaluación, comprobamos que ese carácter sea realmente un número
if ((n2 >= 0) && (n2 <= 9)){
//aumentamos el contador en 1
contador++;
}
else {
System.out.println("Las posiciones 3 - 9 tienen que ser números");
}
}
}
else {
System.out.println("El segundo carácter tiene que ser un guión");
}
}
else{
System.out.println("El primer carácter tiene que ser un número");
}
}else {
System.out.println("El código debe constar de un número + un guión en la segunda posición + 7 números");
}
//si el contador es igual a 7 de cada uno de los 7 números evaluados
if (contador == 7){
//convertimos a String el array de caracteres
String cod = String.valueOf(miChar);
//agregamos el String al ArrayList del catálogo
catalogo.add(cod);
//imprimimos el ArrayList
System.out.println(catalogo);
//reseteamos el contador de los caracteres
contador = 0;
}
//aumentamos en 1 el contador de los pedidos
pedido++;
}
}
}
The intention would be to reduce so much evaluation, I don't know if there will be the possibility of doing a simple if restricting what is requested in a simple line like:
if (caracteres [0-9], '-', [0-9], [0-9], [0-9], [0-9], [0-9], [0-9], [0-9])
All the best
EDITED
Impressive, thank you all very much for the answers, finally, the code has been like this:
public class RestriccionesComprimidas {
public static void main(String[] args){
Scanner teclado = new Scanner(System.in);
String codigo;
int pedido = 1;
ArrayList<String> catalogo = new ArrayList<String>();
while (pedido <= 3){
System.out.println("Introduzca el código: ");
codigo = teclado.nextLine();
Pattern pat = Pattern.compile("^[0-9]-[0-9]{7}$");
Matcher mat = pat.matcher(codigo);
if ((mat.matches()) && (codigo.length() == 9)) {
catalogo.add(codigo);
System.out.println(catalogo);
}else{
System.out.println("El código debe constar de: \n"
+ "- Primer carácter un número \n"
+ "- Segundo carácter un guión \n"
+ "- Siguientes 7 carácter serán números");
}
pedido++;
}
teclado.close();
}
}
Thanks for your help
You can have something like this: the regular expression you need to validate the data is:
To use regular expressions in Java, use the
package java.util.regex
This has two classes that would greatly facilitate the solution to your problem: Pattern and Matcher. Your code would look like this:Based on the comments on my somewhat complicated answers, I leave you with two ways to solve the problem. The first without the need for regular expressions (which are ideal in this case), the second using them.
Solution 1
Note: To improve the way of knowing if it is a number or not, we will create a method that returns boolean if each character of a String is a digit (number). To do this, we will use the method that returns the UNICODE
codePointAt()
code of the character, which in turn is backwards compatible with ASCII . As we can see, the digit codes go from 48 to 57, so we will use that as a reference in the solution.It should be noted that:
isNumeric
and the first character is passed to it.isNumeric
is static so that it can be used within another static context ( main ), it is also private, since it is only used within the class in which it is declared and defined, thus following the principle of least privilege.Solution 2
This is much better than the first solution and makes use of the Pattern class since we are going to use regular expressions . Here is an incredibly useful cheat sheet .
The pattern you ask for is X-XXXXXXX, where each X is a number. Using the cheat sheet , we can then build the following regex:
Where:
^
Tells you to evaluate the start of the string[0-9]
(it can also be\d
because they are synonyms) represents any digit between 0 and 9.-
(Indicates an explicit hyphen)[0-9]{7}
Indicates that the previous group ([0-9]
) must be exactly 7 times$
It indicates that the chain should end thereAs you will see, the program is greatly simplified, since a text pattern can be evaluated
It should be noted that:
pattern.matcher(code).matches()
continue
helps us to skip the rest of the iteration,Final note:
Almost nobody mentions it when starting to program, but it is good practice to close the Scanner
scanner.close();
when we stop using it, since it is a data input ( Input Stream ) that requests resources from the operating system. Although at the end of the execution of the program the JVM closes everything, it is "bad" or rather harmful, not to close the resources that you request.