getchar,
Flux stdin
Le mécanisme d'entrée le plus simple consiste à lire un caractère provenant de l'entrée standard. Suivant le contexte, cette entrée standard peut prendre différente formes.
Sur un ordinateur, les caractères sont généralement lus à partir d'un clavier. Ils peuvent cependant provenir de différents «canaux» : fichiers, redirections de flux ou opérations de séquencement entre les programmes de la couche Shell (pipes ou tubes).
Sur un système embarqué les caractères peuvent provenir des même canaux. Sans système d'exploitation, la liste des canaux est limitée aux interfaces disponibles. Dans les exemples présentés dans ce document, c'est la liaison série qui sert le plus souvent de flux d'entrée standard.
Par principe, la fonction getchar transmet au
programme appelant le caractère suivant de la file d'entrée à chaque
appel.
putchar,
Flux stdout
Par analogie avec le cas de l'entrée standard, le mécanisme le plus simple consiste à émettre un caractère vers la sortie standard. Suivant le contexte cette sortie standard peut aussi prendre différentes formes.
Sur un ordinateur, les caractères sont émis par défaut vers le terminal (ie. la fenêtre du Shell courant). Comme pour toute manipulation au niveau Shell, les opérations de séquencement, de redirection et les tubes sont utilisables. Voir les exemples d'exécution ci-après.
Ces mécanismes d'entrées-sorties standard ont été définis avec les systèmes d'exploitation UNIX au début des années 70. On les retrouve aujourd'hui sur la totalité des systèmes d'exploitation contemporains. Les files d'attentes des caractères issus de l'écran, du clavier, des fichiers stockés sur tous types de supports, etc. sont appelés flux d'entrées-sorties (input-output streams). Des flux standards ont été définis ; chacun étant dédié à un «pseudo-périphérique».
stdin : flux d'entrée ; généralement le
clavier,
stdout : flux de sortie ; généralement
l'écran,
stderr : flux d'erreurs vers lequel sont
redirigés tous les messages d'erreurs lors de l'exécution d'un
programme,
stdprn : flux d'impression ; généralement
le port parallèle,
stdaux : flux auxiliaire ; généralement
le port série.
Voici un exemple simple de programme utilisant les flux d'entrées-sorties
standard via les fonctions getchar et
putchar. Ce programme recopie les caractères reçus sur le
flux d'entrée stdin vers le flux de sortie
stdout. Cette copie se poursuit tant que le caractère
saisi est différent du code ASCII de délimitation de fin de
fichier EOF (code obtenu en appuyant simultanément sur les
touches Ctrl + D).
Exemple 9. Utilisation des fonctions getchar &
putchar avec GCC
01: #include <stdio.h>
02:
03: int main() {
04:
05: char c;
06:
07: while ((c = getchar()) != EOF)
08: putchar(c);
09:
10: return 0;
11: }
L'exemple d'exécution du programme ci-dessous montre que l'opération de
transfert d'un flux vers l'autre est séquencée par le caractère de saut de
ligne \n. Le flux d'entrée se «remplit» tant qu'aucun appui
sur la touche Entrée n'intervient. Dès que le code
ASCII du saut de ligne entre dans le flux d'entrée standard,
son contenu est transféré au programme utilisateur via l'appel à la fonction
getchar.
Les appels à la fonction putchar suivent le même
fonctionnement vis-à-vis du flux de sortie standard.
Voici un exemple d'exécution du programme gcc_stdio.c :
$ ./gcc_stdio.out test test 123 123
Voici deux autres exemples d'exécution du même programme en utilisant les opérations de séquencement entre les programmes offertes par le Shell.
On commence par créer un fichier test.txt à l'aide
de la commande cat. Tous les caractères saisis au clavier
sont redirigés vers le fichier. L'opération s'arrête
avec la saisie du code ASCII EOF
(Ctrl + D).
Le programme est exécuté avec une nouvelle redirection :
./stdio <test.txt. Avec cette redirection, le
contenu du fichier test.txt se substitue au flux
d'entrée standard stdin.
Le programme est à nouveau exécuté en utilisant un
tube (pipe). En fait, deux
programmes sont exécutés : cat test.txt et
stdio. Le premier à pour but d'afficher le contenu du
fichier texte sur le flux de sortie standard stdout
(ie. la console). Le fonctionnement du second programme a déjà été décrit
ci-dessus. L'utilisation du tube permet de transférer la
sortie du premier programme vers l'entrée du second.
phil@b0x:~/src$ cat >test.txt Fichier texte exemple phil@b0x:~/src$ ./stdio <test.txt Fichier texte exemple phil@b0x:~/src$ cat test.txt | ./stdio Fichier texte exemple
Pour plus de détails sur les manipulations à la console, voir Linux - Base d'administration pour le superutilisateur.
Voici maintenant le même exemple simple de programme utilisant les flux
d'entrées-sorties standard sur un système spécialisé. Dans ce contexte sans
système d'exploitation, on ne dispose pas de définition des flux
stdin et stdout entre le
noyau et le Shell. On continue cependant à
utiliser les fonctions getchar et
putchar.
La technique usuelle sur les systèmes spécialisés consiste à donner une nouvelle définition de ces deux fonctions en désignant explicitement le canal de réception et d'émission des caractères. Dans l'exemple, c'est la liaison série entre le PC de développement et le système spécialisé qui sert à faire transiter les caractères dans les deux sens.
Exemple 10. Utilisation des fonctions getchar &
putchar sur microcontrôleur MSC120 avec SDCC
01: #include <stdio.h>
02: #include <msc1210.h>
03: #include "ser_msc1210.h"
04:
05: #define EOF 0x04
06: #define CR 0x0d
07:
08: char getchar(void) {
09: return ser_getc();
10: }
11:
12: void putchar(char c) {
13: ser_putc(c);
14: }
15:
16: void main(void) {
17:
18: char c;
19:
20: // Press <Enter> for auto baudrate adjust
21: autobaud();
22: EA=1;
23:
24: while ((c = getchar()) != EOF) {
25: if (c == CR)
26: putcr();
27: putchar(c);
28: }
29: putcr();
30: putchar('!');
31: putcr();
32:
33: while (1);
34: }
Comme on l'a déjà indiqué, il n'existe pas de couche Shell dans ce contexte. On ne dispose donc pas d'opération de séquencement entre programmes puisque cet exemple est le seul programme exécuté par le microcontrôleur.
Voici un exemple d'exécution du programme sdcc_stdio.c :
MSC1210 Ver:000305F10 >M0000 ok >M8000 ok >E >T > >azerty 123 !
Exemple 3, « Calcul des nombres de Fibonacci sur GNU/Linux avec GCC » : ce programme ne fait pas
directement appel aux fonctions getchar et
putchar. Il utilise plutôt les fonctions
d'entrées-sorties formatées décrites ci-après.
Exemple 4, « Calcul des nombres de Fibonacci sur microcontrôleur MSC1210 avec
SDCC » : lignes 11 à 13. La
liaison série étant utilisée comme canal d'entrée-sortie standard, on définit
la fonction putchar en conséquence. Cette définition est
ensuite réutilisée pour les sorties formatées lors des appels à la fonction
printf : lignes 27, 31, 34, 42 et 45. Pour la
saisie du nombre de calcul, la fonction ser_gets_echo
est définie dans le fichier d'en-tête
ser_msc1210.h.
Vous êtes ici :