vendredi 10 août 2012

Fonctions d'entrées/sorties les plus utilisées

Fonctions d'entrées/sorties les plus utilisées

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