Etape 1

Quelques exercices pour débuter

Voici quelques exercices pour découvrir les premiers éléments du langage : variables scalaires, chaines, entrées-sorties standard et fichiers, boucle while, etc.


**************************************************
***  Conseils généraux pour les TP ***
**************************************************

Chaque exercice idéalement doit être testé, compris et parfois complété. Pour être sauvegardé comme fichier éventuellement modifié puis exécuté, chaque source fourni devra être collé dans un éditeur de texte (sous Linux, Quanta, Kwrite par exemple).
Il est conseillé de ranger les exercices dans des sous-répertoires spécifiques au TP. Les noms des fichiers sont proposés avec l'extension .pl (qui ne joue aucun role, juste un signe de reconnaissance, ...).
Sous Linux, les fichiers pour être exécutables doivent porter la permission x. Si nécessaire donner cette permission en passant la commande, comme root : chmod a+x * dans leur répertoire.
Chaque script doit indiquer le chemin vers Perl avec cette 1ère ligne :  #!/usr/bin/perl -w

 
  Appel direct à Perl en ligne de commande
Syntaxe : perl -e ' < bloc d'instructions PERL >'
On va essayer de tester et de comprendre les exemples suivants:

---------------------------------------------
perl -v

e1e01

---------------------------------------------
man perl

e1e021


Résultat de la commande:

e1e022

---------------------------------------------
man perlfunc

e1e031


Résultat de la commande:

e1e032

---------------------------------------------
perl -e '$prenom ="Jean"; print "Bonjour $prenom\n"'

e1e041

On crée une variable $prenom dans laquelle on ajoute un contenu (un prénom c'est mieux). Puis on affiche à l'écran le texte "Bonjour + variable contenant le prénom + retour à la ligne"


Résultat de la commande:

e1e042

---------------------------------------------
perl -e 'foreach $i (0..10) { print "7x$i = ",7*$i,"\n" ;}'

Comme dans un script on peut créer des boucles. Ici on crée la table de multiplication de 7.
Pour chaque $i de 1 à 10, on affiche "7xle chiffre contenu dans la variable $i = " et on donne le calcul avec 7*le chiffre contenu dans la variable $i.


Résultat de la commande:

e1e051

---------------------------------------------
perl -e '$n=7; foreach $i (0..100) {printf "%3d x %3d = %5d\n" , $n, $i, $n*$i;}'

Pour chaque $i de 0 à 100, on affiche un entier fois un entier = un entier. Le premier est désigné par la variable $n qui contient le chiffre 7, la variable $i quant à elle correspond à un chiffre allant de 0 à 100, c'est le deuxième entier. Enfin le résultat désigné par %5d correspond à la multiplication de la variable $n par $i ($n*$i).

printf signifie qu’on affiche sous contrôle d’un format.
%d désigne un entier en base 10.


Résultat de la commande:

e1e06

---------------------------------------------
 
  Une variable simple (dite "scalaire") est un identificateur toujours précédé du symbole $.
print, l'instruction d'affichage, ne fait pas passer à la ligne automatiquement, c'est le role du caractère \n, qu'il faudra donc utiliser systématiquement.

On exécute le petit script ci-dessous :

--------------------------------------------------------------------
#!/usr/bin/perl -w
$age = 25; $prenom ="Jean"; $salut = "Bonjour";
$s1 = "Bonjour $prenom\n" ;
print $s1;
$s2 = 'Bonjour $prenom\n' ;
print $s2;
$s3 =  $salut." ".$prenom."\n"; print $s3;
$s4 = "$salut $prenom\n"; print $s4;
--------------------------------------------------------------------

Fichier contenant le programme: cliquez!!


Le résultat obtenu est:

e1e11

Lorsqu'on compare le contenu des variables $1 et $2‚ on remarque qu'avec les guillemets doubles la variable $prenom et le retour à la ligne \n sont bien interprétés et remplacés par leurs valeurs alors qu'avec les guillemets simples ne permettent pas d'interprétées les valeurs: on affiche directement ce qui est entre eux, c'est-à-dire, le nom de la variable et \n.
Donc quand il y a des guillemets doubles, on a une interpolation du contenu (interprétation) ce qui n'est pas le cas avec des guillemets simples.


Puis lorsqu'on compare $3 et $4‚ on peut tout de suite remarquer qu'il y a plusieurs façons de concaténer des variables.On peut mettre les chaînes de caractères entre guillemets et les variables seront reliées aux chaînes de caractères par un point (les variables ne seront alors pas entre guillemets): $salut." ".$prenom."\n". Mais on peut aussi tout mettre en guillemets:  "$salut $prenom\n".




On modifie ensuite le programme pour qu'il affiche:

Bonjour Jean
As-tu vraiment 25 ans?



Fichier contenant le programme modifié: cliquez!!


Le résultat est alors le suivant:

e1e12
 
   Les accès aux fichiers s'effectuent habituellement par l'intermédiaire de variables particulières appelées filehandles, en français descripteurs de fichiers.
Perl dote chaque programme exécuté de 3 descripteurs prédéfinis, STDIN, STDOUT et STDERR (reprise des canaux standard d'Unix : entrée clavier, sortie écran, sortie en erreur) qui sont immédiatement utilisables sans déclaration, contrairement aux accès à des fichiers réels.

L'opérateur de lecture sur l'entrée standard (le clavier) est noté <STDIN>, souvent abrégé en <>. Un appel à cet opérateur lit la ligne saisie jusqu'au prochain caractère "nouvelle ligne" (y compris). L'instruction chomp $var permet de retirer ce caractère \n de la chaine et renvoie 1 s'il réussit.
/!\ Ne pas la confondre avec chop $var qui retire le dernier caractère quel qu'il soit et le renvoie.

La sortie standard sur l'écran, est noté <STDOUT>. L'écriture, ici l'affichage écran, s'effectue avec print, sous la syntaxe générale : print STDOUT $texte; qu'il est agréable d'abréger en : print $texte.



Fichier contenant le programme: cliquez!!

e1e22

Le résultat:

e1e31

Le code du programme ci-dessus  est-il correct ?

Tout d'abord on peut enlever STDOUT après print, il n'est pas nécessaire de préciser quelque chose qui est déjà établi ainsi par défaut.
Ensuite, le retour chariot n'a pas été supprimé ce qui fait qu'après le prénom on a un retour à la ligne, il aurait fallu utiliser la fonction chomp sur la variable $prenom (chomp $var). Enfin, on peut voir que les accents ne sont pas toujours supportés donc il vaut mieux éviter de les mettre afin de s'épargner un affichage aussi bancal que celui que nous avons.



On va donc corriger le programme et le complèter en demandant aussi l'âge!

Fichier contenant le programme: cliquez!!

e1e23


Le résultat sera le suivant:

e1e24
 
  ---------------------------------------------
#!/usr/bin/perl -w
print "\$a = ";
$a = <>;
---------------------------------------------

Dans le code ci-dessus, quel est le role du caractère \ devant $a ?


Le \ devant la variable $a déspécialise cette variable, c'est-à-dire qu'elle sera considérée comme une chaîne de caractères.


Faire lire 2 variables numériques $a et $b, à l'aide de l'opérateur <>

Fichier contenant le programme: cliquez!!

e1e311

Le résultat:

e1e31


Faire afficher le résultat de l'addition sous la forme: $a + $b = 200 + 350 = 550.

Fichier contenant le programme: cliquez!!

e1e32

Le résultat:

e1e33



Prolongement : à l'aide d'une itération while, afficher la table de multiplication par N (N saisi).

Fichier contenant le programme: cliquez!!

e1e34

Et le résultat:

e1e35

 
 
---------------------------------------------
#!/usr/bin/perl -w
print "Saisir une nouvelle ligne : ";
while ($ligne = <>) {
$texte .= $ligne;
}
print "Vous avez saisi le texte \n $texte \n";
---------------------------------------------

Avec le programme ci-dessus, on va saisir des lignes au clavier dans une boucle while (tant que) avec l'opérateur <>. La fin de la saisie est provoquée par l'envoi du caractère Ctrl-d (eof) sur une ligne vide.

Fichier contenant le programme: cliquez!!

e1e41

Et le résultat est:

e2e41r

La fin de la ligne de saisie est provoquée par l'envoi de Ctrl-d qui annonce l'eof, c'est-à-dire la "End of File", soit la fin du fichier (ou script).

L'affichage est identique à la saisie pour la simple raison qu'on a récupéré le texte dans le fichier <> qui correspond à l'entrée standard (au clavier) donc à ce qui a été directement saisi.


On réécrit le même programme en se servant de la variable $_. Le programme fonctionnera exactement de la même manière vu que la variable $_ contient la dernière ligne lue.


Fichier contenant le programme: cliquez!!
e1e42
Le résultat:

e2e42r




                        
 
  La fonction open associe au fichier spécifié un filehandle (descripteur de fichier):

Syntaxe:

e1e51

Chaque appel à l'opérateur "chevron" appliqué au descripteur F, provoque la lecture de la ligne suivante dans le fichier.
L'instruction print F $chaine (attention, pas de virgule !) écrit la chaine comme un enregistrement dans le fichier.
Rappel : en l'absence de descripteur, print envoie ses arguments sur la sortie standard, c'est-à-dire l'écran.


On expérimente le programme ci-dessous:

e1e52


Fichier contenant le programme: cliquez!!

e1e53

Tant qu’il y a une ligne du fichier pointé sous le nom F à lire, on exécute un bloc d’instructions.
 
  On écrit un programme qui lit le nom d'un fichier dans lequel on veut saisir un texte via la console.  On va ouvrir le fichier en ajout, créer une boucle dans laquelle chaque ligne saisie au clavier est directement  écrite dans le fichier.  Puis après la boucle, on affichera le contenu du fichier pour contrôler ce qui a été fait!

Fichier contenant le programme: cliquez!!

Dans le terminal on aura (sans saisir un nom de fichier):

e2e61

Fichier contenant le résultat: cliquez!!


Ou, si on saisit un nom de fichier:

e2e62

Fichier contenant le résultat: cliquez!!

 
  Dans ce programme, on va lire le nom du fichier à copier, ici les premières lignes d'Anna Karénine de Tolstoï, (s'il n'existe pas, le nom sera "essai.txt"), on va lire le nom du fichier qui doit contenir la copie (par défaut "copie.txt"), puis on va ouvrir ces 2 fichiers en lecture ou en écriture. Tant qu'il y a une ligne à lire dans le fichier source, la copier dans le fichier cible, Enfin, pour contrôler, afficher le contenu du fichier copié.

Fichier de travail: cliquez!!

Fichier contenant le programme: cliquez!!

Dans le terminal on aura (sans saisir un nom de fichier):

e1e73

Le résultat:

e1e74

Fichier contenant le résultat: cliquez!!


Ou, si on saisit un nom de fichier:

e1e71

Le résultat:

e1e72


Fichier contenant le résultat: cliquez!!