
L'objectiu d'aquest CodeLab és aprendre a llegir correctament i validar les dades d'entrada d'un programa.
Quan implementem un programa no tenim control sobre les dades d'entrada que rebrà. El desajust entre el tipus de dades que espera un programa i el tipus de dades que, efectivament, rep, és una font de errors molt comuna. Per exemple, un programa espera llegir de l'entrada un nombre de tipus enter i el que es troba és una cadena de text. Aquesta circumstància és molt comú quan les dades d'entrada les introdueix l'usuari amb el teclat, encara que també es pot donar quan es llegeixen les dades d'un fitxer o de la xarxa.
Una norma bastant acceptada és la de llegir sempre l'entrada com a text, i tractar de convertir-la al tipus desitjat dintre del programa.
En aquest CodeLab programarem una petita aplicació de gestió d'alumnes, i utilitzarem els mètodes de conversió de tipus que ofereix Java per a validar les dades.
Per últim, aprendrem també a com facilitar la introducció repetitiva de dades quan estem desenvolupant un programa i hem d'anar fent proves sobre el seu funcionament.
Inicia IntelliJ i crea un nou projecte "Java"..

Marca l'opció "Command Line App":

Posa-li de nom

Utilitzarem aquesta petita aplicació de gestió per a aprendre a tractar la validació de dades. Copia-la al teu projecte.
import java.util.Scanner; class Alumne { String nom; float nota; } public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); Alumne[] alumnes = new Alumne[10]; int posicio = 0; while(true) { System.out.println(); System.out.println("GESTIO ALUMNES"); System.out.println("a) Introduir alumne"); System.out.println("b) Llistar alumnes"); System.out.println(); String opcio = scanner.nextLine(); switch (opcio) { case "a": alumnes[posicio] = new Alumne(); System.out.println("Nom: "); alumnes[posicio].nom = scanner.nextLine(); System.out.println("Nota: "); alumnes[posicio].nota = scanner.nextFloat(); scanner.nextLine(); // descartem l'intro de després del float posicio++; break; case "b": System.out.println("Llistat d'alumnes"); for (int i = 0; i < posicio; i++) { System.out.println(alumnes[i].nom + ": " + alumnes[i].nota); } break; default: return; } } } }
Prova l'aplicació.
Quan llegim dades de tipus
Però què passa si quan tractem de llegir la nota amb

Ens trobem amb un desajust amb les dades d'entrada (
Una possible solució bastant comú és llegir les dades sempre amb
nota = Float.parseFloat(scanner.nextLine());
Ara bé, això no soluciona -de moment- el problema, ja que si l'usuari introdueix un text, el programa no fallarà en la lectura de dades, però sí en la conversió:

Ara l'error és en el format de número (
Per a corregir aquest nou error hem de fer una petita introducció a la sentència de control
La sentència
El bloc de la sentència
En el nostre exemple, podem posar en el bloc
try { nota = Float.parseFloat(scanner.nextLine()); } catch (Exception e){ System.out.println("La nota introduïda no és valida"); }
D'aquesta manera el nostre programa no finalitzarà amb l'exepció
Només queda una última consideració. El programa no fallarà però, amb quin valor quedarà la nota d'aquell alumne? Efectivament, quedarà amb un
Caldrà donar la opció a l'usuari de tornar a introduir la nota fins que aquesta sigui vàlida. O dit en pensament computacional, caldrà tornar a demanar la nota a l'usuari mentre (
do { System.out.println("Nota: "); try { alumnes[posicio].nota = Float.parseFloat(scanner.nextLine()); break; } catch (Exception e) { System.out.println("La nota introduïda no és valida"); } } while(true);
El programa complet queda finalment així:
import java.util.Scanner; class Alumne { String nom; float nota; } public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); Alumne[] alumnes = new Alumne[10]; int posicio = 0; while(true) { System.out.println(); System.out.println("GESTIO ALUMNES"); System.out.println("a) Introduir alumne"); System.out.println("b) Llistar alumnes"); System.out.println(); String opcio = scanner.nextLine(); switch (opcio) { case "a": alumnes[posicio] = new Alumne(); System.out.println("Nom: "); alumnes[posicio].nom = scanner.nextLine(); do { System.out.println("Nota: "); try { alumnes[posicio].nota = Float.parseFloat(scanner.nextLine()); break; } catch (Exception e) { System.out.println("La nota introduïda no és valida"); } } while(true); posicio++; break; case "b": System.out.println("Llistat d'alumnes"); for (int i = 0; i < posicio; i++) { System.out.println(alumnes[i].nom + ": " + alumnes[i].nota); } break; default: return; } } } }
Cada cop que fas una modificació el codi, executes el programa i introdueixes les dades per veure com va funcionant el programa.

Això significa una valuosa pèrdua de temps, que podem evitar posant les dades d'entrada en un arxiu i llegint les dades directament de l'arxiu.
Crea un arxiu de text al directori arrel de projecte (

Modifica la construcció de l'
Scanner scanner = new Scanner(new File("dades"));
Es mostrarà un error subratllat en vermell. Polsa

Ja està, això és tot el que has de fer, ara ja pots executar el teu programa i fer tantes proves com vulguis, sense haver d'introduir cada cop les dades.