Vous êtes sur la page 1sur 26

Royaume du Maroc

OFFICE DE LA FORMATION PROFESSIONNELLE ET DE LA PROMOTION DU TRAVAIL

Cours13T
Langage C et Gestion des Entres/Sorties
Rsum de Thorie
Version prliminaire

Deuxime Anne
Programme de Formation des Techniciens
Spcialiss en lectronique
DIRECTION DE LA RECHERCHE ET INGENIERIE DE LA FORMATION
Septembre 1996

Rsum de Thorie

Langage C et Gestion des Entres/Sorties

TECCART INTERNATIONAL 2000 inc.


3155, rue Hochelaga,
Montral, Qubec (Canada)
H1W 1G4

RDACTION
Robert Pesant
DESSINS ET CONCEPTION GRAPHIQUE
Robert Pesant
RVISION TECHNIQUE
Robert Pesant
RVISION LINGUISTIQUE
Franois Gaudreau

COMMISSION DE VALIDATION
Formateurs de lOFPPT

Les droits de reproduction et de diffusion de ce document sont cds par Teccart


International 2000 inc. lOffice de la Formation Professionnelle et de la Promotion du
Travail du Royaume du Maroc, pour sa propre utilisation au Maroc.
Mis part lOFPPT, toute reproduction, en tout ou en partie, par quelque procd que ce
soit, est interdite.

Imprim Montral, le j May


270915432.doc

Modles de programme

Page 2

OFPPT/TECCART

Rsum de Thorie

Langage C et Gestion des Entres/Sorties

TABLE DES MATIRES


5. MODLES DE PROGRAMME
05.1 Introduction
15.2 Constantes symboliques
25.3 Modle #1: Attendre le choix de l'usager
05.3.1 Avec verrouillage explicite..........................................................................................
15.3.2 Avec verrouillage inhrent..........................................................................................
35.4 Modle #2: Excuter une tche tout en scrutant le clavier
45.5 Dtection des codes tendus du clavier IBM
25.5.1 Codes tendus du clavier............................................................................................
35.5.2 Dtection des codes tendus seulement......................................................................
45.5.3 Dtection simultane des codes ASCII et tendus......................................................
55.6 Utilisation des modles pour dbuter un programme dapplication
65.7 Rappel sur l'usage des fichiers d'en-tte

Modles de programme

Page 3

OFPPT/TECCART

Modles de programme
Introduction
La presque totalit des programmes d'application peuvent tre labors partir de deux modles
standards.
Le premier modle de programmes consiste prsenter un menu l'usager, attendre sa
dcision, excuter la tche choisie et retourner au menu pour attendre la prochaine
intervention.
Le deuxime modle de programmes consiste excuter une tche de faon continuelle,
surveiller priodiquement le clavier, traiter la demande de l'usager et reprendre, par la suite, la
tche en cours.
Des exemples de ces deux modles seront prsents dans ce chapitre.
On y dcrira aussi les techniques de verrouillage des touches du clavier non dsires: par
exemple, lorsque l'usager se voit offrir les choix A, B ou C, il faut que le programme soit
insensible toutes les autres touches. Dans le langage familier, on parle de doter le programme
d'un anticabochon(!) S'il faut utiliser des instructions pour verrouiller certaines touches, on parle
de verrouillage explicite; si la structure mme du programme empche un choix qui ne fait pas
partie du menu, on parle de verrouillage inhrent. Il est important de prciser que ces deux
techniques ne sont pas associes un modle de programme particulier. Toutefois, leur usage sera
dmontr par les deux premiers programmes conus selon le modle #1.
On profitera aussi de l'occasion pour montrer comment dtecter les codes tendus des touches
comme F1, F2, PageUp, ...
Enfin, on rappellera comment liminer les avertissements du compilateur pour que les
programmes respectent le Standard ANSI.
Mais avant dentrer dans le vif du sujet, nous allons introduire la notion de constante symbolique.

Constantes symboliques
Jusqu' maintenant, la seule directive au prprocesseur rencontre dans les programmes est
#include. Comme vous le savez, elle sert inclure les fichiers d'en-tte. Pour dfinir les
constantes symboliques, nous aurons besoin dune autre directive au prprocesseur. Il s'agit de
#define.
Mais quest-ce quune constante symbolique? Cest un identificateur auquel le prprocesseur
substitue la chane de caractres qui lui est associe par #define. Tout comme l'identificateur
d'une variable ou d'une fonction, l'identificateur d'une constante symbolique est limit un
maximum de 31 caractres dans le Standard ANSI. Ces caractres peuvent tre des lettres et/ou
des chiffres et/ou le caractre de soulignement. On ne doit toutefois pas dbuter par un chiffre.
Pour tre conforme au style adopt au chapitre 2, l'identificateur d'une constante symbolique sera
toujours crit en majuscules seulement.
titre dexemple, nous avons modifi le programme TESTFOR.C du chapitre prcdent.
Lanalyse de TESTFOR1.C met en vidence les deux principaux rles des constantes
symboliques:
1.
remplacer les chanes de caractres encombrantes pour allger un programme;
2.
remplacer certaines constantes numriques pour donner plus de signification au
programme.

/* Programme:
* =========
*
* Auteur:
* Date:
* Rvision:
* Version:
*
* Volume:
* Fichier:
*
* Description:
*
*/

TESTFOR1.C
==========
Robert Pesant
24/02/1996
24/02/1996
V1.1
COURS_13T
\CHAP.005\TESTFOR1.C
Modification de TESTFOR.C pour dmontrer
l'utilisation des constantes symboliques.

#include <stdio.h>
#include <conio.h>
#define
#define
#define
#define

TITRE1
TITRE2
A_MAJ
Z_MAJ

"Impression des codes ASCII (65 90)\n"


"====================================\n\n"
65
90

void main(void)
{
int i;
clrscr();
printf(TITRE1);
printf(TITRE2);
for(i = A_MAJ; i <= Z_MAJ ; i++)
{
putch(i); putch(' ');
}
}

printf("\n\nFin!\a");

Modle #1: Attendre le choix de l'usager


Avec verrouillage explicite
La Figure
explicite.

5 -1 prsente lordinogramme du programme du Modle #1 avec verrouillage

Aprs la prsentation du menu, le programme attend l'intervention de l'usager. S'il choisit de


terminer, le programme sort au DOS. Sinon, le programme teste immdiatement la validit du
choix: s'il est incohrent, il retourne attendre la prochaine intervention.
C'est seulement si le choix fait partie de la liste offerte que le programme poursuit son excution
en effectuant la tche associe l'option choisie ainsi que la tche commune toutes les options
s'il y a lieu.
Le programme MODEL_1A.C a t conu partir de cet ordinogramme. La boucle principale
du programme, do ... while(1);, est une boucle sans fin car la valeur numrique 1 est toujours
VRAIE. La sortie au DOS devra donc se faire de l'intrieur mme de cette boucle.
Au tout dbut de la boucle principale, une autre boucle do ... while joue deux rles importants.
Premirement, elle protge le programme contre les choix incohrents de l'usager. On dit que
c'est du verrouillage explicite car l'instruction prcise la condition pour laquelle le programme
reste captif de la boucle; si le choix est diffrent des codes ASCII '1' et '2' et '3' et 27 (ESC),
c'est--dire si l'usager n'a pas appuy sur 1, 2, 3 ou Esc, le programme ne peut voluer vers la
tche suivante: do ... while(ERR_CHOIX);.

Dbut

Prsenter
le menu

A
Attendre le choix
de l'usager

OUI

choix

illgal

NON

choix
option_1

==
?

OUI

Excuter
tche_1

OUI

Excuter
tche_2

OUI

Excuter
tche_3

Excuter
tche_commune

Excuter
tche_quitter

Fin

NON

choix
option_2

==
?

NON

choix
option_3

==
?

NON

F I G U R E 5- 1: M O D L E # 1A. V E R R O U I L L AG E

EXPLICITE

Deuximement, si l'usager appuie sur la touche Esc, elle permet la sortie au DOS par l'appel de la
fonction exit(). Le paramtre de cette fonction est pass au DOS et peut tre test dans un batch
file par la commande if errorlevel; on utilise toujours 0 pour une sortie normale.
La suite du programme est constitue par une instruction slective switch ... case, o se trouvent
les instructions de chaque option du menu, et par quelques instructions communes chacune de
ces options.
Chargez le programme sur la disquette et faites en l'essai. Vrifiez l'efficacit de la technique de
verrouillage explicite.

/* Programme:
* =========
*
* Auteur:
* Date:
* Rvision:
* Version:
*
* Volume:
* Fichier:
*
* Description:
*
*
*
*
*/
#include
#include
#include
#include

MODEL_1A.C
==========
Robert Pesant
24/02/1996
24/02/1996
V1.0
COURS_13T
\CHAP.005\MODEL_1A.C
Modle de programme qui
1.
attend, sans rien faire, le choix de l'usager,
2.
excute la tche choisie et
3.
retourne l'tape 1 lorsque la tche est termine.
Ce programme est dot d'un verrouillage explicite.

<stdio.h>
<conio.h>
<string.h>
<process.h>

#define
#define
#define
#define
#define

TITRE1
TITRE2
TITRE3
TITRE4
TITRE5

""
" Modle de programmes #1A:
"
" Attente du choix de l'usager "
" (... verrouillage explicite) "
""

#define
#define
#define
#define
#define

MENU1
MENU2
MENU3
MENU4
MENU5

"Tche #1 .....
"Tche #2 .....
"Tche #3 .....
"Quitter ......
"Votre choix ..

#define
#define
#define
#define

TEXTE1
TEXTE2
TEXTE3
TEXTE4

"Excution
"Excution
"Excution
"Retour au

< 1 >"
< 2 >"
< 3 >"
<Esc>"
< * >"

de la
de la
de la
menu:

tche #1..."
tche #2..."
tche #3..."
une touche, SVP"

#define ESC

27

#define ERR_CHOIX

(choix != '1') && (choix != '2') && (choix != '3') && (choix != ESC)

void main(void)
{
int choix;
clrscr();
gotoxy(41
gotoxy(41
gotoxy(41
gotoxy(41
gotoxy(41

strlen(TITRE1)/2,
strlen(TITRE2)/2,
strlen(TITRE3)/2,
strlen(TITRE4)/2,
strlen(TITRE5)/2,

gotoxy(41
gotoxy(41
gotoxy(41
gotoxy(41
gotoxy(41

strlen(MENU1)/2, 8); printf(MENU1);


strlen(MENU2)/2, 9); printf(MENU2);
strlen(MENU3)/2, 10); printf(MENU3);
strlen(MENU4)/2, 11); printf(MENU4);
strlen(MENU5)/2, 12); printf(MENU5);

do

{
do

1);
2);
3);
4);
5);

printf(TITRE1);
printf(TITRE2);
printf(TITRE3);
printf(TITRE4);
printf(TITRE5);

{
gotoxy(48, 12); putch('*'); gotoxy(48, 12);

/* La valeur 'int' retourne de getche() est le code ASCII de la touche enfonce */


choix = getche();
}
while(ERR_CHOIX);

switch(choix)
{
/* Code ASCII dcimal de la touche < 1 > = 49 ou '1' */
case '1':
gotoxy(41 - strlen(TEXTE1)/2, 19); printf(TEXTE1);
break;
/* Code ASCII dcimal de la touche < 2 > = 50 ou '2' */
case '2':
gotoxy(41 - strlen(TEXTE2)/2, 19); printf(TEXTE2);
break;
/* Code ASCII dcimal de la touche < 3 > = 51 ou '3' */
case '3':
gotoxy(41 - strlen(TEXTE3)/2, 19); printf(TEXTE3);
break;

/* Code ASCII dcimal de la touche <Esc> = 27 */


case ESC:
clrscr(); exit(0);
}
gotoxy(41 - strlen(TEXTE4)/2, 20); printf(TEXTE4);
getch();
gotoxy(1, 19); clreol();
gotoxy(1, 20); clreol();
}
while(1);

L'nonc #define TITRE1 ""


renferme des caractres graphiques non accessibles directement par les touches du clavier (
moins d'utiliser un gestionnaire (driver) de clavier spcial). Pour utiliser les caractres graphiques
et les symboles spciaux dans vos textes, reportez-vous lAnnexe 2: La table des codes
ASCII. Consultez les colonnes Caractre et Pav numrique pour trouver le caractre dsir.
Appuyez sur la touche Alt pendant que vous tapez le code ASCII dcimal du caractre sur le
pav numrique du clavier. Ce caractre apparatra lorsque vous relcherez la touche Alt.
La Figure 5 -2 montre le menu offert l'usager et illustre le comportement du programme durant
lexcution dune tche choisie par lutilisateur.

F I G U R E 5-2: E X C U T I ON

DE

M O DE L _ 1 A. E X E

Avec verrouillage inhrent


La technique du verrouillage inhrent s'applique seulement aux programmes qui ne comportent
pas de tche commune aux options d'un menu.
En fait, cette technique ne fait appel aucune protection explicite: lorsque le choix de l'usager est
incohrent, le programme passe travers la boucle principale sans rien excuter car...
3.
il n'y a pas de tche dfinie pour cette option et
4.
il n'y a pas de tche commune toutes les options.
La structure de ce genre de programme est dcrite par lordinogramme de la Figure 5 -3.

Dbut

Prsenter
le menu

A
Attendre le choix
de l'usager

choix
option_1

==
?

OUI

Excuter
tche_1

OUI

Excuter
tche_2

OUI

Excuter
tche_3

OUI

Excuter
tche_quitter

NON

choix
option_2

==
?

NON

choix
option_3

==
?

NON

choix
option_quitter

==
?

Fin

NON

F I G U R E 5- 3: M O D L E # 1B. V E R R OU I L L AG E

INHRENT

Le programme MODEL_1B.C illustre la technique de verrouillage inhrent. La boucle principale


du programme est encore ralise l'aide de la boucle do ... while(1);. Au dbut de cette boucle
se trouve l'instruction choix = getche(); qui accepte sans distinction le choix de l'usager.
L'instruction switch ... case qui suit offre la protection inhrente dsire en ne traitant que les
options valides, incluant celle de quitter au DOS.
Faites l'essai du programme et vrifiez qu'il est bien protg contre les manipulations douteuses.
/* Programme:
* =========
*
* Auteur:
* Date:
* Rvision:
* Version:
*
* Volume:
* Fichier:
*
* Description:
*
*
*
*
*/
#include
#include
#include
#include
#include

MODEL_1B.C
==========
Robert Pesant
24/02/1996
24/02/1996
V1.0
COURS_13T
\CHAP.005\MODEL_1B.C
Modle de programme qui
1.
attend, sans rien faire, le choix de l'usager,
2.
excute la tche choisie et
3.
retourne l'tape 1 lorsque la tche est termine.
Ce programme est dot d'un verrouillage inhrent.

<stdio.h>
<conio.h>
<string.h>
<process.h>
<dos.h>

#define
#define
#define
#define
#define

TITRE1
TITRE2
TITRE3
TITRE4
TITRE5

""
" Modle de programmes #1B:
"
" Attente du choix de l'usager "
" (... verrouillage inhrent) "
""

#define
#define
#define
#define
#define

MENU1
MENU2
MENU3
MENU4
MENU5

"Tche #1 .....
"Tche #2 .....
"Tche #3 .....
"Quitter ......
"Votre choix ..

#define
#define
#define
#define
#define
#define

TEXTE1
TEXTE2
TEXTE3
TEXTE4
TEXTE5
TEXTE6

"Excution de la tche #1 ... Patientez ..."


"CHARGE!!!..."
"Excution de la tche #2 ... Patientez ..."
"OUCH!!!..."
"Excution de la tche #3 ... Patientez ..."
"C'est tout!!!..."

#define ESC

< 1 >"
< 2 >"
< 3 >"
<Esc>"
< * >"

27

void main(void)
{
int choix, x;
clrscr();
gotoxy(41
gotoxy(41
gotoxy(41
gotoxy(41
gotoxy(41

strlen(TITRE1)/2,
strlen(TITRE2)/2,
strlen(TITRE3)/2,
strlen(TITRE4)/2,
strlen(TITRE5)/2,

1);
2);
3);
4);
5);

printf(TITRE1);
printf(TITRE2);
printf(TITRE3);
printf(TITRE4);
printf(TITRE5);

gotoxy(41
gotoxy(41
gotoxy(41
gotoxy(41
gotoxy(41

strlen(MENU1)/2, 8); printf(MENU1);


strlen(MENU2)/2, 9); printf(MENU2);
strlen(MENU3)/2, 10); printf(MENU3);
strlen(MENU4)/2, 11); printf(MENU4);
strlen(MENU5)/2, 12); printf(MENU5);

do

{
gotoxy(48, 12); putch('*'); gotoxy(48, 12);
/* La valeur 'int' retourne de getche() est le code ASCII de la touche enfonce */
choix = getche();
switch(choix)
{
/* Code ASCII dcimal de la touche < 1 > = 49 ou '1' */
case '1':
gotoxy(41 - strlen(TEXTE1)/2, 19); printf(TEXTE1);
sound(262); delay(150); nosound(); delay(20);
sound(349); delay(150); nosound(); delay(20);
sound(440); delay(150); nosound(); delay(20);
sound(523); delay(200); nosound(); delay(150);
sound(440); delay(200); nosound(); delay(20);
sound(523); delay(350); nosound();
gotoxy(41 - strlen(TEXTE2)/2, 21); printf(TEXTE2);
sleep(1);
break;
/* Code ASCII dcimal de la touche < 2 > = 50 ou '2' */
case '2':
gotoxy(41 - strlen(TEXTE3)/2, 19); printf(TEXTE3);
gotoxy(71, 21); putch('O');
for(x = 11; x <= 69; x++)
{
gotoxy(x, 21); printf("->");
delay(100);
}
gotoxy(1, 21); clreol();
gotoxy(41 - strlen(TEXTE4)/2, 21); printf(TEXTE4);
sleep(1);
break;
/* Code ASCII dcimal de la touche < 3 > = 51 ou '3' */
case '3':
gotoxy(41 - strlen(TEXTE5)/2, 19); printf(TEXTE5);
sleep(3);
gotoxy(41 - strlen(TEXTE6)/2, 21); printf(TEXTE6);
sleep(1);
break;

/* Code ASCII dcimal de la touche <Esc> = 27 */


case ESC:
clrscr(); exit(0);
}
gotoxy(1, 19); clreol(); gotoxy(1, 21); clreol();
}
while(1);

Comme le montre la Figure 5 -4, l'usager se voit offrir un menu comportant trois choix. Elle
illustre galement comment le programme ragit visuellement dans les trois cas. Il ne manque
videmment que le son...

F I G U R E 5- 4: E X C U T I O N

DE

MO DE L_ 1 B. E X E

Modle #2: Excuter une tche tout en scrutant le clavier


Dans ce deuxime modle, le programme excute une tche de faon continuelle, surveille
priodiquement le clavier, traite la demande de l'usager et reprend, par la suite, la tche en cours.

Dbut

Prsenter
le menu

A
Excution de la
tche principale
rptitive

Scrutation du
clavier

Aucune
touche
dtecte?

OUI

NON

choix
option_1

==
?

OUI

Excuter
tche_1

OUI

Excuter
tche_2

OUI

Excuter
tche_3

OUI

Excuter
tche_quitter

NON

choix
option_2

==
?

NON

choix
option_3

==
?

NON

choix
option_quitter

==
?

NON

F I G U R E 5-5: M OD L E #2 A. C O D E S AS CI I

Fin

La Figure 5 -5 dcrit cette stratgie. Pour l'instant, seules les touches qui font partie du code
ASCII sont dtectes: on parle ici des lettres, des chiffres et des signes de ponctuation. La
dtection des codes tendus fera l'objet de la discussion la section suivante.
Ds le dmarrage, le programme entre dans une boucle pour effectuer une tche rptitive
quelconque.
la fin de l'excution d'une squence, dcrite par le bloc d'instructions de la boucle, le tampon du
clavier est test pour savoir si une touche a t enfonce. S'il n'y a eu aucune intervention de
l'usager, la squence est reprise immdiatement. Par contre, si une touche est dtecte, elle est
identifie et la tche correspondante est excute, avant la reprise de la squence.
Vous remarquerez que l'on a utilis ici la technique du verrouillage inhrent. Il est trs important
de prciser que ce n'est pas le modle du programme qui impose la technique de verrouillage,
mais bien le genre de tche qui doit tre accomplie l'aide de ce modle. Dans le mme ordre
d'ide, le Modle #1, labor prcdemment, ne dtectait que les codes ASCII du clavier; il est
certain qu'ventuellement un programme construit selon ce modle pourra exiger la dtection des
codes tendus: il faudra l'adapter en consquence.
Le programme MODEL_2A.C a t conu partir du Modle #2.
La scrutation du clavier s'effectue l'aide de la fonction kbhit(). Le rle de cette fonction est de
lever un drapeau (flag) lorsque le tampon du clavier contient au moins un code; kbhit() ne vide
pas ce tampon. On doit obligatoirement utiliser getch() ou getche() pour rcuprer le code de la
touche et nettoyer par le fait mme le tampon du clavier.
Faites l'essai du programme en vous limitant pour dbuter aux touches standards: les lettres, les
chiffres et les signes de ponctuations. Puis, essayez les touches de fonction et de dplacement de
curseur: vous constaterez que le clavier gnre deux codes que le programme traite comme deux
codes standards individuels.
/* Programme:
* =========
*
* Auteur:
* Date:
* Rvision:
* Version:
*
* Volume:
* Fichier:
*
* Description:
*
*
*
*
*
*
*
*
*
*
*
*
*/
#include
#include
#include
#include
#include

MODEL_2A.C
==========
Robert Pesant
24/02/1996
24/02/1996
V1.0
COURS_13T
\CHAP.005\MODEL_2A.C
Modle de programme qui
1.
excute une tche continuellement,
2.
surveille le clavier,
3.
interrompt la tche pour traiter la demande
4.
et retourne l'tape 1 pour continuer.
Cette stratgie peut s'appliquer pour d'autres
priphriques que le clavier.
Le programme peut aussi surveiller plus d'un seul
priphrique la fois.
Cette mthode est appelle: "Polling".
Ce programme est conu pour effectuer seulement
la dtection des codes ASCII du clavier IBM.

<stdio.h>
<conio.h>
<string.h>
<process.h>
<dos.h>

#define
#define
#define
#define
#define
#define

TITRE1
TITRE2
TITRE3
TITRE4
TITRE5
TITRE6

""
" Modle de programmes #2A:
"
"
Excution d'une tche et
"
"
surveillance du clavier . "
" (.. codes ASCII seulement) "
""

#define
#define
#define
#define
#define

CHAS1
CHAS2
CHAS3
CHAS4
CHAS5

""
"
CHASER
"
""
" "
""

#define
#define
#define
#define

MENU1
TEXTE1
TEXTE2
ESC

"Appuyez sur une touche (<Esc> pour quitter) ..."


"Aucune touche date ..."
"La dernire touche enfonce est: [ * ]"

27

void main(void)
{
int touche, x=37;
clrscr();
gotoxy(41
gotoxy(41
gotoxy(41
gotoxy(41
gotoxy(41
gotoxy(41

strlen(TITRE1)/2,
strlen(TITRE2)/2,
strlen(TITRE3)/2,
strlen(TITRE4)/2,
strlen(TITRE5)/2,
strlen(TITRE6)/2,

1);
2);
3);
4);
5);
6);

printf(TITRE1);
printf(TITRE2);
printf(TITRE3);
printf(TITRE4);
printf(TITRE5);
printf(TITRE6);

gotoxy(41
gotoxy(41
gotoxy(41
gotoxy(41
gotoxy(41

strlen(CHAS1)/2,
strlen(CHAS2)/2,
strlen(CHAS3)/2,
strlen(CHAS4)/2,
strlen(CHAS5)/2,

9);
10);
11);
12);
13);

printf(CHAS1);
printf(CHAS2);
printf(CHAS3);
printf(CHAS4);
printf(CHAS5);

gotoxy(41 - strlen(MENU1 )/2,


gotoxy(41 - strlen(TEXTE1)/2,
do

16); printf(MENU1 );
18); printf(TEXTE1);

{
do

{
if(x == 37)
{
gotoxy(44, 12);
}
else
{
gotoxy(x-1, 12);
}
putch('');
gotoxy(x, 12); putch(' ');
x = (x == 44) ? 37: x+1;
delay(100);
}
while(!kbhit());
touche = getch();
switch(touche)
{
/* Code ASCII dcimal de la touche <Esc> = 27 */
case ESC:
clrscr();
exit(0);
break;
default:
gotoxy(41 - strlen(TEXTE2)/2, 18);
printf("La dernire touche enfonce est: [ %c
sound(300); delay(100);
sound(400); delay(100);
nosound();
}
}
while(1);

]", touche);

Nous avons soumis le programme quelques essais. Les rsultats apparaissent la Figure 5 -6.

F I G U R E 5-6: E X C U T I ON

DE

M O DE L _ 2 A. E X E

Dtection des codes tendus du clavier IBM


Codes tendus du clavier
Certaines touches ne sont pas reprsentes dans le jeu des 256 codes ASCII: ce sont, entre
autres, les touches de fonction, de dplacement de curseur et les combinaisons de touches
dbutant par Ctrl, Shift et Alt.
L'essai du programme MODEL_2A.C a rvl que ces touches particulires sont reprsentes
par deux codes ASCII: le premier code est toujours ASCII 0 et le deuxime, le code tendu
proprement dit, est donn l'Annexe 3: La table des codes tendus du clavier.
Les programmes, qui suivent, prsentent les stratgies pour la dtection des codes tendus
seulement et pour la dtection simultane des codes ASCII et tendus.
Dtection des codes tendus seulement
Le programme MODEL_1B.C a t modifi pour que l'usager fasse son choix dans le menu
l'aide des touches F1, F2 et F3. Cette nouvelle version du programme s'intitule MODEL_1C.C.
Vous remarquerez qu'il est conu selon le Modle #1 et qu'il fait encore appel la technique du
verrouillage inhrent.
Pour dtecter seulement les codes tendus, il suffit d'extraire les codes ASCII du tampon du
clavier jusqu' ce qu'on trouve le code tendu qui est diffrent de ASCII 0. Ce code doit tre
interprt par le programme qui excutera, par la suite, la tche correspondante. Lordinogramme
dcrivant cette technique est prsent la Figure 5 -7.
Dbut

Attendre et lire
une touche
OUI

code ==
ASCII 0
?
NON

Interprter le
code tendu

Fin

F I G U R E 5- 7: S T R AT G I E

DE DTECTION DES CODES TENDUS

Dans le programme en C, c'est par l'instruction itrative suivante que la dtection des codes
tendus s'effectue:
do

{
choix = getch();
}
while(choix == 0);

Voici l'imprim complet de MODEL_1C.C. Faites-en l'analyse et l'essai.


/* Programme:
* =========
*
* Auteur:
* Date:
* Rvision:
* Version:
*
* Volume:
* Fichier:
*
* Description:
*
*
*
*
*
*/
#include
#include
#include
#include
#include

MODEL_1C.C
==========
Robert Pesant
24/02/1996
24/02/1996
V1.0
COURS_13T
\CHAP.005\MODEL_1C.C
Modle de programme qui
1.
attend, sans rien faire, le choix de l'usager,
2.
excute la tche choisie et
3.
retourne l'tape 1 lorsque la tche est termine.
Ce programme est dot d'un verrouillage inhrent et
effectue la dtection des codes tendus.

<stdio.h>
<conio.h>
<string.h>
<process.h>
<dos.h>

#define
#define
#define
#define
#define

TITRE1
TITRE2
TITRE3
TITRE4
TITRE5

""
" Modle de programmes #1C:
"
" Attente du choix de l'usager "
" (.. codes tendus seulement) "
""

#define
#define
#define
#define
#define

MENU1
MENU2
MENU3
MENU4
MENU5

"Tche #1 .....
"Tche #2 .....
"Tche #3 .....
"Quitter ......
"Votre choix ..

#define
#define
#define
#define
#define
#define

TEXTE1
TEXTE2
TEXTE3
TEXTE4
TEXTE5
TEXTE6

"Excution de la tche #1 ... Patientez ..."


"CHARGE!!!..."
"Excution de la tche #2 ... Patientez ..."
"OUCH!!!..."
"Excution de la tche #3 ... Patientez ..."
"C'est tout!!!..."

#define ESC

<
<
<
<
<

F1
F2
F3
Esc
*

>"
>"
>"
>"
>"

27

void main(void)
{
int choix, x;
clrscr();
gotoxy(41
gotoxy(41
gotoxy(41
gotoxy(41
gotoxy(41

strlen(TITRE1)/2,
strlen(TITRE2)/2,
strlen(TITRE3)/2,
strlen(TITRE4)/2,
strlen(TITRE5)/2,

1);
2);
3);
4);
5);

printf(TITRE1);
printf(TITRE2);
printf(TITRE3);
printf(TITRE4);
printf(TITRE5);

gotoxy(41
gotoxy(41
gotoxy(41
gotoxy(41
gotoxy(41

strlen(MENU1)/2, 8); printf(MENU1);


strlen(MENU2)/2, 9); printf(MENU2);
strlen(MENU3)/2, 10); printf(MENU3);
strlen(MENU4)/2, 11); printf(MENU4);
strlen(MENU5)/2, 12); printf(MENU5);

do

{
gotoxy(47, 12); putch(' '); putch('*'); gotoxy(48, 12);
do

{
choix = getch();
}
while(choix == 0);
switch(choix)
{
/* Code tendu de la touche < F1 > = ';' */
case ';':
gotoxy(47, 12); printf("F1");
gotoxy(41 - strlen(TEXTE1)/2, 19); printf(TEXTE1);
sound(262); delay(150); nosound(); delay(20);
sound(349); delay(150); nosound(); delay(20);
sound(440); delay(150); nosound(); delay(20);
sound(523); delay(200); nosound(); delay(150);
sound(440); delay(200); nosound(); delay(20);
sound(523); delay(350); nosound();
gotoxy(41 - strlen(TEXTE2)/2, 21); printf(TEXTE2);
sleep(1);
break;
/* Code tendu de la touche < F2 > = '<' */
case '<':
gotoxy(47, 12); printf("F2");
gotoxy(41 - strlen(TEXTE3)/2, 19); printf(TEXTE3);
gotoxy(71, 21); putch('O');
for(x = 11; x <= 69; x++)
{
gotoxy(x, 21); printf("->");
delay(100);
}
gotoxy(1, 21); clreol();
gotoxy(41 - strlen(TEXTE4)/2, 21); printf(TEXTE4);
sleep(1);
break;
/* Code tendu de la touche < F3 > = '=' */
case '=':
gotoxy(47, 12); printf("F3");
gotoxy(41 - strlen(TEXTE5)/2, 19); printf(TEXTE5);
sleep(3);
gotoxy(41 - strlen(TEXTE6)/2, 21); printf(TEXTE6);
sleep(1);
break;

/* Code ASCII dcimal de la touche <Esc> = 27 */


case ESC:
clrscr(); exit(0);
}
gotoxy(1, 19); clreol(); gotoxy(1, 21); clreol();
}
while(1);

Les rsultats obtenus l'excution de MODEL_1C.C sont identiques ceux de MODEL_1B.C;


il n'y a que les touches offertes au menu qui diffrent (c.f. Figure 5 -8).

F I G U R E 5-8: M E N U

P R S E N T PAR

M O DE L _ 1 C. E X E

Dtection simultane des codes ASCII et tendus


La stratgie de dtection simultane des codes ASCII et tendus du clavier est illustre la
Figure 5 -9.
Si le premier code lu est diffrent de ASCII 0, c'est un code ASCII qui doit tre interprt
immdiatement. Par contre, s'il est identique ASCII 0, une deuxime lecture du tampon du
clavier doit tre effectue pour extraire le code tendu qui l'accompagne. L'interprtation de ce
deuxime code peut, ce moment, tre excute.
Dbut

Attendre et lire
une touche

code ==
ASCII 0
?

OUI

NON

Interprter le
code ASCII

Attendre et lire
une touche

Fin

Interprter le
code tendu

Fin

F I G U R E 5- 9: S T R AT G I E

DE DTECTION DES CODES

AS CI I

ET TENDUS

Le programme MODEL_2B.C est une modification de MODEL_2A.C. Dans cette nouvelle


version, les codes ASCII ainsi que les codes tendus sont traits. Un seul getch() ou getche() est
ncessaire pour extraire les codes ASCII du tampon du clavier, alors qu'il en faut deux pour les
codes tendus.

/* Programme:
* =========
*
* Auteur:
* Date:
* Rvision:
* Version:
*
* Volume:
* Fichier:
*
* Description:
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
#include
#include
#include
#include
#include

MODEL_2B.C
==========
Robert Pesant
24/02/1996
24/02/1996
V1.0
COURS_13T
\CHAP.005\MODEL_2A.C
Modle de programme qui
1.
excute une tche continuellement,
2.
surveille le clavier,
3.
interrompt la tche pour traiter la demande
4.
et retourne l'tape 1 pour continuer.
Cette stratgie peut s'appliquer pour d'autres
priphriques que le clavier.
Le programme peut aussi surveiller plus d'un seul
priphrique la fois.
Cette mthode est appelle: "Polling".
Ce programme est conu pour effectuer simultanment
la dtection des codes ASCII et tendus
du clavier IBM.

<stdio.h>
<conio.h>
<string.h>
<process.h>
<dos.h>

#define
#define
#define
#define
#define
#define

TITRE1
TITRE2
TITRE3
TITRE4
TITRE5
TITRE6

""
" Modle de programmes #2A:
"
"
Excution d'une tche et
"
"
surveillance du clavier
"
" (... codes ASCII et tendus) "
""

#define
#define
#define
#define
#define

CHAS1
CHAS2
CHAS3
CHAS4
CHAS5

""
"
CHASER
"
""
" "
""

#define MENU1

"Appuyez sur une touche (<Esc> pour quitter) ..."

#define TEXTE1
#define TEXTE2
#define TEXTE3

"Aucune touche date ..."


"La dernire touche enfonce est: [ 0 * ] (code tendu)"
"La dernire touche enfonce est: [ * ] (code ASCII) "

#define ESC

27

void main(void)
{
int touche, x=37;
clrscr();
gotoxy(41
gotoxy(41
gotoxy(41
gotoxy(41
gotoxy(41
gotoxy(41

strlen(TITRE1)/2,
strlen(TITRE2)/2,
strlen(TITRE3)/2,
strlen(TITRE4)/2,
strlen(TITRE5)/2,
strlen(TITRE6)/2,

1);
2);
3);
4);
5);
6);

printf(TITRE1);
printf(TITRE2);
printf(TITRE3);
printf(TITRE4);
printf(TITRE5);
printf(TITRE6);

gotoxy(41
gotoxy(41
gotoxy(41
gotoxy(41
gotoxy(41

strlen(CHAS1)/2,
strlen(CHAS2)/2,
strlen(CHAS3)/2,
strlen(CHAS4)/2,
strlen(CHAS5)/2,

9);
10);
11);
12);
13);

printf(CHAS1);
printf(CHAS2);
printf(CHAS3);
printf(CHAS4);
printf(CHAS5);

gotoxy(41 - strlen(MENU1 )/2,


gotoxy(41 - strlen(TEXTE1)/2,

16); printf(MENU1 );
18); printf(TEXTE1);

do

{
do

{
if(x == 37)
{
gotoxy(44, 12);
}
else
{
gotoxy(x-1, 12);
}
putch('');
gotoxy(x, 12); putch(' ');
x = (x == 44) ? 37: x+1;
delay(100);
}
while(!kbhit());
touche = getch();
gotoxy(1, 18); clreol();
gotoxy(1, 19); clreol();
switch(touche)
{
/* Code ASCII dcimal de la touche <Esc> = 27 */
case ESC:
clrscr();
exit(0);
break;
/* Les codes du clavier pour les touches de fonction, de direction,
de tabulation, ... dbutent par le code ASCII '0' suivi du
code tendu de la touche. Un deuxime getch() est
ncessaire pour extraire ce deuxime code du tampon
du clavier.
Si un menu offrait un choix pour <F1>, <F2> et <F3> par
exemple, un deuxime "switch ... case" serait ncessaire
dans le "case 0" qui suit pour assigner des tches
spcifiques chacune de ces trois touches. */
case 0:
touche = getch();
gotoxy(41 - strlen(TEXTE2)/2, 18);
printf("La dernire touche enfonce est: [ 0 %c ] (code tendu)", touche);
sound(350); delay(100);
sound(450); delay(100);
nosound();
break;

}
while(1);

default:
gotoxy(41 - strlen(TEXTE3)/2, 18);
printf("La dernire touche enfonce est: [
sound(300); delay(100);
sound(400); delay(100);
nosound();
}

%c

] (code ASCII) ", touche);

La Figure 5 -10 montre quelques exemples typiques de ce que l'on obtient l'excution du
programme:

F I G U R E 5-1 0: E X C U T I O N

DE

MO DE L_ 2 B. E X E

Utilisation des modles pour dbuter un programme dapplication


Lorsque nous avons un programme rdiger, les questions, qui se posent souvent, sont Par o
dois-je dbuter? Quest-ce que jcris en premier lieu? . chaque fois, nous avons limpression
de rinventer la roue . Si nous prenons lhabitude de penser en fonction des modles de
programme, la solution deviendra vidente et simple.
Voici la mthode propose.
5.
Dterminez en premier lieu le modle de programme qui correspond votre application.
6.
Faites une copie du programme slectionn et changez son nom en fonction de votre
application: copy model_2a.c meteo.c.
7.
Modifiez ce fichier source pour ladapter votre application.
Modifiez le commentaire en dbut de programme.
Ajoutez ou retranchez des choix dans linstruction switch...case.
Dans chaque case, remplacez les instructions du programme de dmonstration par
les instructions ncessaires votre application.

Rappel sur l'usage des fichiers d'en-tte


Au chapitre 2, nous avons prsent la recette d'utilisation de la directive au prprocesseur
#include dans un programme en C. Il est important d'en faire ici le rappel si l'on veut que nos
programmes respectent le Standard ANSI. Notez qu'on parle toujours de recette car il est
encore trop tt pour expliquer de quoi se compose un fichier d'en-tte.
Le directive au prprocesseur #include est utilise pour insrer dans le programme source un
fichier d'en-tte comme conio.h ou stdio.h. Dans tous les exemples prsents jusqu' maintenant,
on retrouve en dbut de programme des lignes comme celles-ci:
8.
#include <stdio.h>
9.
#include <conio.h>
Ces fichiers d'en-tte sont ncessaires pour aider le compilateur dtecter les erreurs de syntaxe
dans l'appel des fonctions de la bibliothque. Il faut donc s'assurer de spcifier, dans un #include,
le fichier d'en-tte de chaque fonction de la bibliothque que l'on utilise dans le programme.
La procdure recommande se compose des tapes suivantes.
10. Compilez le fichier source xxx.C l'aide de la commande Compile/Compile. Si vous
obtenez les avertissements No declaration for function 'xxx' et Call to function
'xxx' with no prototype, c'est qu'il manque le fichier d'en-tte correspondant la
fonction mentionne.
11. Placez le curseur sur l'identificateur de la fonction et appuyez sur Ctrl-F1 pour faire
apparatre le menu d'aide. Vous y trouverez le nom du fichier d'en-tte xxx.H qui doit
tre insr par une directive #include.
12. Compilez nouveau le fichier source xxx.C l'aide de la commande Compile/Compile,
pour vous assurer que tous les avertissements (warnings) ont t limins.