Le langage C se veut
totalement indépendant du matériel sur lequel il est implanté. Les entrées
sorties, bien que nécessaires à tout programme (il faut lui donner les données
de départ et connaître les résultats), ne font donc pas partie intégrante du
langage. On a simplement prévu des bibliothèques de fonctions de base, qui sont
néanmoins standardisées, c'est à dire que sur chaque compilateur on dispose de
ces bibliothèques, contenant les même fonctions (du moins du même nom et
faisant apparemment la même chose, mais programmées différemment en fonction du
matériel). Ces bibliothèques ont été définies par la norme ANSI, on peut donc
les utiliser tout en restant portable. Nous détaillerons ici deux bibliothèques
: CONIO.H et STDIO.H.
Dans CONIO.H on trouve
les fonctions de base de gestion de la console :
putch(char) : affiche sur l'écran (ou du moins stdout) le
caractère fourni en argument (entre parenthèses). stdout est l'écran, ou un
fichier si on a redirigé l'écran (en rajoutant >nomfichier derrière l'appel
du programme, sous DOS ou UNIX). Si besoin est, cette fonction rend le
caractère affiché ou EOF en cas d'erreur.
getch(void) : attend le prochain appui sur le clavier, et rend le
caractère qui a été saisi. L'appui sur une touche se fait sans écho, c'est à
dire que rien n'est affiché à l'écran. En cas de redirection du clavier, on
prend le prochain caractère dans le fichier d'entrée.
getche(void) : idem getch mais avec écho. On pourrait réécrire
cette fonction en fonction des deux précédentes :
char getche(void);
{
char
caractere;
caractere=getch();
putch(caractere);
return(caractere);
}
ou même {return(putch(getch))}
Dans la pratique, ce n'est
pas ainsi que getche est réellement défini, mais en assembleur pour un résultat
plus rapide.
Dans STDIO.H, on
trouve des fonctions plus évoluées, pouvant traiter plusieurs caractères à la
suite (par les fonctions de conio.h), et les transformer pour en faire une
chaîne de caractères ou une valeur numérique, entière ou réelle par exemple. Les
entrées sont dites "bufférisées", c'est à dire que le texte n'est pas
transmis, et peut donc encore être modifié, avant le retour chariot.
puts(chaîne) affiche, sur stdout, la chaîne de caractères puis
positionne le curseur en début de ligne suivante. puts retourne EOF en cas d'erreur.
gets(chaîne) lecture d'une chaîne sur stdin. Tous les caractères
peuvent être entrés, y compris les blancs. La saisie est terminée par un retour
chariot. Gets retourne un pointeur sur le premier caractère entré (donc égal à
son paramètre d'entrée, ou le pointeur NULL en cas d'erreur (fin du fichier
stdin par exemple).
printf(format,listevaleurs) affiche la liste de valeurs (variables ou expressions)
dans le format choisi. Le format est une chaîne de caractères entre guillemets (doubles
quote "), dans laquelle se trouve un texte qui sera écrit tel quel, des
spécifications de format (débutant par %) qui seront remplacées par la valeur
effective des variables, dans l'ordre donné dans listevaleurs, et de caractères
spéciaux (\). Printf retourne le nombre de caractères écrits, ou EOF en cas de
problème.
Une spécification de
format est de la forme :
% [flag][largeur][.précision][modificateur]type
(entre [] facultatifs)
Le flag peut
valoir : - (cadrage à gauche, rajout de blancs si nécessaire à droite), + (impression
du signe, même pour les positifs), blanc (impression d'un blanc devant un
nombre positif, à la place du signe), 0 (la justification d'un nombre se ferra
par rajout de 0 à gauche au lieu de blancs). D'autres Flags sont possibles mais
moins utiles, pour plus de détails voir l'aide en ligne de Turbo C.
La largeur est
le nombre minimal de caractères à écrire (des blancs sont rajoutés si
nécessaire). Si le texte à écrire est plus long, il est néanmoins écrit en
totalité. En donnant le signe * comme largeur, le prochain argument de la liste
de valeurs donnera la largeur (ex printf("%*f",largeur,réel)).
La précision
définit, pour les réels, le nombre de chiffres après la virgule (doit être
inférieur à la largeur). Dans la cas d'entiers, indique le nombre minimal de
chiffes désiré (ajout de 0 sinon), alors que pour une chaîne (%s), elle indique
la longueur maximale imprimée (tronqué si trop long). La précision peut, comme
la largeur, être variable en donnant .*
Le modificateur
peut être : h (short, pour les entiers), l (long pour les entiers, double pour
les réels), L (long double pour les réels).
Le type est : c
(char), s (chaîne de caractères, jusqu'au \0), d (int), u (entier non signé), x
ou X (entier affiché en hexadécimal), o (entier affiché en octal), f (réel en
virgule fixe), e ou E (réel en notation exponentielle), g ou G (réel en f si
possible, e sinon), p (pointeur), % (pour afficher le signe %).
Les caractères
spéciaux utilisables dans le format sont \t (tabulation), \n (retour à la ligne),
\\ (signe \), \nb tout code ASCII, en décimal, hexa ou octal (\32=\040=\0x20='
').
scanf(format,listeadresse) lecture au clavier de valeurs, dans le format
spécifié. Les arguments sont des pointeurs sur les variables résultats (dans le
cas de variables scalaires, les précéder par l'opérateur &). Scanf retourne
le nombre de valeurs effectivement lues et mémorisées (pas les %*).
Le format peut
contenir (entre ") : du texte (il devra être tapé exactement ainsi par l'utilisateur,
et ne sera pas stocké), des séparateurs blancs (l'utilisateur devra taper un ou
plusieurs blancs, tabulations, retours à la ligne), et des spécifications de
format, sous la forme %[*][largeur][modificateur] type.
* signifie que la
valeur sera lue mais ne sera pas stockée (ex scanf("%d%*c%d",&i,&j)
: lecture de deux entiers séparés par n'importe quel caractère)
la largeur est la
largeur maximale lue, scanf s'arrête avant s'il trouve un séparateur (blanc, tab,
CR).
les modificateurs et
types sont les mêmes que pour printf (excepté d,o,x : pour entiers short, D,O,X
pour long). Dans le cas des chaînes (%s), le blanc est également un séparateur.
On ne pourra donc pas entrer une chaîne avec des blancs par scanf, il faut
utiliser gets.
Scanf lit dans stdin
en considérant les retours chariot (CR) comme des blancs. on peut donc séparer
par des CR plusieurs valeurs demandées dans le même scanf. Mais de même, si
scanf a pu lire tous ses arguments sans arriver à la fin de la ligne, la suite
servira au prochain scanf. Utilisez gets(bidon) avant (pour être sur de
commencer sur une nouvelle ligne) ou après scanf (pour ignorer la fin de la
ligne) si nécessaire.
getchar(void) fonctionne comme getche, mais utilise le même tampon
que scanf.
On dispose aussi de sprintf(chaîne,
format, listevaleurs) qui permet d'écrire dans une chaîne plutôt que sur l'écran,
et donc faire des conversions numériques ->ASCII; et de sscanf(chaîne, format,l
isteadresse) qui lit dans une chaîne plutôt qu'au clavier. On possède
encore d'autres fonctions dans STDIO, en particulier pour gérer les fichiers.
Aucun commentaire:
Enregistrer un commentaire