import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException; import java.util.StringTokenizer; /** * Cette classe a pour but de fournir des outils de base pour la * saisie de valeurs de certains type de base.

* Elle a été initialement écrite pour la mise en place des TPs de * JAVA dans les modules d'initiation à la programmation de DEUG MIAS * première année a l'université de Picardie Jules Verne.

* Toutes les méthodes proposées dans la classe Clavier * sont des méthodes de classe (seules méthodes vues au premier semestre). * La manière d'utiliser ces méthodes * est illustrée par l'exemple suivant : *
 
 *    int valeur ;                   // déclaration de la variable  
 *    ... 
 *    valeur = Clavier.lireInt();    // saisie de la valeur 
 *    ... 
 * 
*
* Avertissement 1. La classe Clavier doit, à priori, * être présente dans le * répertoire d'utilisation * à moins que (Aspect Avancés (hors programme première année) ) * le répertoire dans lequel elle est présente * ne soit précisé dans la variable d'environnement CLASSPATH * ou dans l'option -classpath des commandes.

* Avertissement 2. La classe ne fonctionne qu'à partir de la * version 1.2 de JAVA.

* Avertissement 3. Toutes les méthodes (à l'exception de lireLigne) * proposées dans cette classe * ne tiennent pas compte des séparateurs * (espace, tabulation, retour chariot = passage à la ligne) * pour récupérer de l'information. (C'est ce qui se passe dans * beaucoup d'autres langages de programmation * (par exemple langage C, langage Pascal)).
* On appelle entité toute suite de caractères consécutifs * différents de l'espace, de la tabulation ou du retour chariot.

* Informations pour ceux qui cherchent à comprendre * (Aspects Avancés (hors programme première année) ). * */ /* Remarque. Les commentaires du code présente des aspects avancés de programmation (hors programme première année) */ public final class Clavier { /* L'objet buffer: l'initialisation à la valeur null permet de * savoir plus tard que l'objet n'a pas été instancié. */ private static BufferedReader bufIn = null; /* L'objet pour analyser le buffer. On parle d'analyseur lexical. */ private static StringTokenizer st = null; /** * Le fait de mettre en private le constructeur rend * la classe non instanciable.
* Il n'y a qu'un clavier! */ private Clavier() {} /** * Initialise le buffer.
* Les données sont saisies par défaut au clavier * (souvent appelé entrée standard et noté stdin) * Cette action (l'allocation) n'est exécutée qu'une fois.
* Cette fonction est appelée lors de chaque lecture (via la fonction * read(). * */ private static void initialise() { if (bufIn == null) bufIn= new BufferedReader(new InputStreamReader(System.in)); } /* Lecture d'une information dans le buffer */ private static void read() { if (bufIn == null) // Ce test ne peut être vrai qu'une fois initialise(); // définition du buffer try { String s = bufIn.readLine(); // Lecture d'une ligne du buffer st = new StringTokenizer(s); // Instanciation objet d'analyse } catch (IOException e) { System.err.println("read" + " " + e.getMessage()); System.exit(2); // Une erreur s'est produite, on sort du programme. } } /** * vide le tampon (buffer), en supprimant les caractères tapés * jusqu'a cette instruction.
* Entre deux demandes d'information, l'utilisateur peut tapoter sur le * clavier. En faisant appel a flush() avant la saisie d'une information, * cela permet de ne pas tenir compte de ce "tapotage". * BUG RECENSE. Ne vire pas ce qui reste dans le buffer de * plus bas niveau stdin. */ private static void flushTotal() { st = null; bufIn = null ; } /** * vide partiellement le tampon (buffer), * en supprimant les caractères tapés non utilisés sur la dernière ligne. *
* Pour éviter de saisir des informations tapées malencontreusement. */ private static void flush() { st = null; } /** analyse la prochaine entité dans le buffer comme une constante * de type int (entier).
* Les espaces, tabulations et sauts de lignes sont "passés". * La lecture attend l'arrivée d'autres caractères dans le buffer.
* @return le nombre lu de type int * @exception NumberFormatException * erreur si la prochaine entité n'est pas de type int. */ public static int lireInt() { if (st == null) read(); while (! st.hasMoreTokens()) read(); String ss = st.nextToken(); int i = Integer.parseInt(ss); return(i); } /** analyse la prochaine entité dans le buffer comme une constante * de type long (entier).
* Les espaces, tabulations et sauts de lignes sont "passés". * La lecture attend l'arrivée d'autres caractères dans le buffer.
* @return le nombre lu de type long * @exception NumberFormatException * erreur si la prochaine entité n'est pas de type long */ public static long lireLong() { if (st == null) read(); while (! st.hasMoreTokens()) read(); String ss = st.nextToken(); long i = Long.parseLong(ss); return(i); } /** analyse la prochaine entité dans le buffer comme une constante * de type float (réel flottant).
* Les espaces, tabulations et sauts de lignes sont "passés". * La lecture attend l'arrivée d'autres caractères dans le buffer.
* @return le nombre lu de type float * @exception NumberFormatException * erreur si la prochaine entité n'est pas de type float */ public static float lireFloat() { if (st == null) read(); while (! st.hasMoreTokens()) read(); String ss = st.nextToken(); float f = Float.parseFloat(ss); return(f); } /** analyse la prochaine entité dans le buffer comme une constante * de type double (réel flottant en double précision).
* Les espaces, tabulations et sauts de lignes sont "passés". * La lecture attend l'arrivée d'autres caractères dans le buffer.
* @return le nombre lu de type double * @exception NumberFormatException * erreur si la prochaine entité n'est pas de type double */ public static double lireDouble() { if (st == null) read(); while (! st.hasMoreTokens()) read(); String ss = st.nextToken(); double f = Double.parseDouble(ss); return(f); } /** analyse la prochaine entité dans le buffer comme une constante * de type chaine de caractères.
* Les espaces, tabulations et sauts de lignes sont "passés". * La lecture attend l'arrivée d'autres caractères dans le buffer.
* En particulier, on ne peut pas saisir une chaîne vide, ou * une chaîne avec des espaces. * @return la chaine de caractères lue de type String */ public static String lireString() { if (st == null) read(); while (! st.hasMoreTokens()) read(); return(st.nextToken()); } /** Retourne la chaîne composée de tous les caractères rencontrés * jusqu'au prochain retour chariot.
* Permet de saisir une chaîne vide, ou * une chaîne avec des espaces. * Si une information (par exemple un entier) a déjà été récupérée, * ne donne que la fin de la ligne (à partir du premier caractère, * après l'information, différent de l'espace et de la tabulation). * @return la chaine de caractères lue de type String */ public static String lireLigne() { String s = "" ; if ((st == null) || (!st.hasMoreTokens())) { if(bufIn == null) initialise() ; try{ s = bufIn.readLine() ; } catch (IOException e) { System.err.println("lireString" + " " + e.getMessage()); System.exit(2); // Une erreur s'est produite, on sort du programme. } return s ; } else { System.out.println("Autre cas" ) ; return(st.nextToken(System.getProperty("line.separator" ))); } } }