A.3 La classe TC
Le but de cette classe écrite spécialement pour le cours par l'auteur
du présent poly (F. Morain) est de
fournir quelques fonctions pratiques pour les TP, comme des
entrées-sorties faciles, ou encore un chronomètre. Les exemples
qui suivent sont presque tous donnés dans la classe TestTC
qui est dans le même fichier que TC.java (qui se trouve
lui-même accessible à partir des pages web du cours).
A.3.1 Fonctionnalités, exemples
Gestion du terminal
Le deuxième exemple de programmation consiste à demander un entier
à l'utilisateur et affiche son carré. Avec la classe TC, on
écrit :
class TCex{
public static void main(String[] args){
int n;
System.out.print("Entrer n=");
n = TC.lireInt();
System.out.println("n^2=" + (n*n));
}
}
La classe TC contient d'autres primitives de ce type,
comme TC.lireLong, ou encore lireLigne.
Si l'on veut lire plusieurs nombres1, ou bien si on veut les lire sur
l'entrée standard, par exemple en exécutant
unix% java prgm < fichier
il convient d'utiliser la syntaxe :
do{
System.out.print("Entrer n=");
n = TC.lireInt();
if(! TC.eof())
System.out.println("n^2=" + (n*n));
} while(! TC.eof());
qui teste explicitement si l'on est arrivé à la fin du
fichier (ou si on a quitté le programme).
Lectures de fichier
Supposons que le fichier fic.int contienne les entiers
suivants :
1 2 3 4
5
6
6
7
et qu'on veuille récupérer un tableau contenant tous ces
entiers. On utilise :
int[] tabi = TC.intDeFichier("fic.int");
for(int i = 0; i < tabi.length; i++)
System.out.println(""+tabi[i]);
On peut lire des double par :
double[] tabd = TC.doubleDeFichier("fic.double");
for(int i = 0; i < tabd.length; i++)
System.out.println(""+tabd[i]);
La fonction
static char[] charDeFichier(String nomfichier)
permet de récupérer le contenu d'un fichier dans un tableau de
caractères. De même, la fonction
static String StringDeFichier(String nomfichier)
retourne une chaîne qui contient le fichier nomfichier.
On peut également récupérer un fichier sous forme
de tableau de lignes à l'aide de :
static String[] lignesDeFichier(String nomfichier)
La fonction
static String[] motsDeFichier(String nomfichier)
retourne un tableau de chaînes contenant les mots contenus dans
un fichier, c'est-à-dire les chaînes de caractères
séparées par des blancs, ou bien des caractères de tabulation,
etc.
Sortie dans un fichier
Il s'agit là d'une fonctionnalité spéciale. En effet, on souhaite
pouvoir faire à la fois une sortie d'écran normale, ainsi qu'une
sortie simultanée dans un fichier. L'utilisation typique en est la
pale machine.
Pour bénéficier de cette fonctionnalité, on utilise:
TC.sortieFichier("nom_sortie");
TC.print(3);
TC.println(" allo");
ce qui a pour effet d'afficher à l'écran
3 allo
ainsi que d'en faire une copie dans le fichier
nom_sortie. Les fonctions TC.print et
TC.println peuvent être utilisées en lieu et place de
System.out.print et System.out.println.
Si on oublie de faire l'initialisation, pas de problème, les résultats
s'affichent à l'écran comme si de rien n'était.
Conversions à partir des String
Souvent, on récupère une chaîne de caractères (par exemple
une ligne) et on veut la couper en morceaux. La fonction
static String[] motsDeChaine(String s)
retourne un tableau contenant les mots de la chaîne.
Si on est sûr que s ne contient que des entiers séparés
par des blancs (cf. le chapitre sur les polynômes), la fonction
static int[] intDeChaine(String s)
retourne un tableau d'entiers contenus dans s. Par
exemple si s="1 2 3", on récupèrera un tableau contenant
les trois entiers 1, 2, 3 dans cet ordre. Si l'on a affaire à
des entiers de type long, on utilisera :
static long[] longDeChaine(String s)
Utilisation du chronomètre
La syntaxe d'utilisation du chronomètre est la suivante :
long t;
TC.demarrerChrono();
N = 1 << 10;
t = TC.tempsChrono();
La variable t contiendra le temps écoulé pendant
la suite d'opérations effectuées depuis le lancement du chronomètre.
A.3.2 La classe Efichier
Cette classe rassemble des primitives de traitement des fichiers en
entrée. Les explications qui suivent peuvent être omises en
première lecture.
L'idée est d'encapsuler le traitement des fichiers dans une
structure nouvelle, appelée Efichier (pour fichier
d'entrées). Cette structure est définie comme :
class Efichier{
BufferedReader buf;
String ligne;
StringTokenizer tok;
boolean eof, eol;
}
On voit qu'elle contient un tampon d'entrée à la Java, une ligne
courante (ligne), un tokeniser associé (tok), et gère
elle-même les fins de ligne (variable eol) et la fin du
fichier (variable eof). On a défini deux constructeurs :
Efichier(String nomfic){
try{
buf = new BufferedReader(new FileReader(new File(nomfic)));
}
catch(IOException e){
System.out.println(e);
}
ligne = null;
tok = null;
eof = false;
eol = false;
}
Efichier(InputStreamReader isr){
buf = new BufferedReader(isr);
ligne = null;
tok = null;
eof = false;
eol = false;
}
le second permettant d'utiliser l'entrée standard sous la
forme :
static Efichier STDIN = new Efichier(new InputStreamReader(System.in));
La lecture d'une nouvelle ligne peut alors se faire par :
String lireLigne(){
try{
ligne = buf.readLine();
}
catch(EOFException e){
eol = true;
eof = true;
return null;
}
catch(IOException e){
erreur(e);
}
eol = true;
if(ligne == null)
eof = true;
else
tok = new StringTokenizer(ligne);
return ligne;
}
où nous gérons tous les cas, et en particulier
eof ``à la main''. On définit également
lireMotSuivant, etc.
Les fonctionnalités de gestion du terminal sont encapsulées à
leur tour dans la classe TC, ce qui permet d'écrire entre
autres :
class TC{
static boolean eof(){
return Efichier.STDIN.eof;
}
static int lireInt(){
return Efichier.STDIN.lireInt();
}
...
}
- 1
- Ce passage peut être
sauté en première lecture.