Langage C/Entrées-sorties
Durant l’exécution d’un programme, le processeur, qui est le cerveau de l’ordinateur, a besoin de communiquer avec le reste du matériel. Il doit en effet recevoir des informations pour réaliser des actions et il doit aussi en transmettre. Ces échanges d’informations sont les entrées et les sorties(ou input / output pour les anglophones), souvent abrégée E/S (ou I/O).
Les entrées permettent de recevoir une donnée en provenance de certains périphériques. Les données fournies par ces entrées peuvent être une information envoyée par le disque dur, la carte réseau, le clavier, la souris, un CD, un écran tactile, bref par n’importe quel périphérique.Par exemple, notre clavier va transmettre des informations sur les touches appuyées (par exemple 1 et 8) au processeur ou à la mémoire : notre clavier est donc une entrée.
À l’inverse, les sorties vont transmettre des données vers ces périphériques. On pourrait citer l'exemple de l'écran : notre ordinateur lui envoie des informations pour qu’elles soient affichées.
Dans ce chapitre, nous allons apprendre différentes fonctions fournies par le langage C, qui vont nous permettre de recevoir ou d'envoyer des informations sur nos sorties et d’en recevoir sur nos entrées. Vous saurez ainsi comment demander à un utilisateur de rentrer une information au clavier, et comment afficher quelque chose sur la console.
Les sorties
modifierIntéressons-nous dans un premier temps aux sorties. Afin d’afficher un caractère ou même un texte (on préfère le terme de « chaîne de caractères ») à l’écran, il faut utiliser des fonctions. Depuis votre premier code, vous en utilisez une : la fonction main. Une fonction, en simplifiant un peu, est un morceau de code exécutant des instructions. Des instructions qui permettent d’effectuer des opérations (avec par exemple des fonctions mathématiques) sur des variables ou encore d’écrire du texte à l’écran par exemple.
Nous allons voir trois fonctions d’affichage de données dans ce chapitre, je nomme fièrement :
- printf pour écrire une chaîne de caractères formatée ;
- puts pour écrire une chaîne de caractères toute simple ;
- putchar pour écrire un caractère.
printf — Écrire une chaîne de caractères de manière formatée
modifierLa fonction printf affiche donc une chaîne de caractères (c'est-à-dire du texte) à l’écran. On l'utilise comme ceci :
printf("Votre texte...");
Cette fonction permet non seulement d'afficher des chaînes de caractères simples, mais également la valeur d'une variable passée en paramètre. Pour ce faire, il suffit d’utiliser un indicateur de conversion : il s'agit du caractère spécial % suivi d'une lettre qui varie en fonction du type de la variable.
Voici les indicateurs de conversions de la norme C89 :
Type | Indicateurs de conversions |
---|---|
char | %c |
int | %d |
long | %ld |
short | %hd |
float | %f |
double | %f |
long double | %Lf |
unsigned int | %u |
unsigned short | %hu |
unsigned long | %lu |
Après d’avoir inscrit un indicateur de conversion dans la chaîne de caractère (dans les guillemets ""), il faut indiquer de quelle variable il faut afficher la valeur. Il suffit de rajouter une virgule après les ces derniers, suivis du nom de la variable, comme ceci :
printf("%[lettre]", variable_a_afficher);
Essayez donc d’afficher la valeur de la variable pi :
/* Cette variable est constante (utilisation de « const »)
car la valeur de pi ne change jamais */
const double pi = 3.141596;
printf("pi = %f", pi);
pi = 3.141596
C’est tout simple. Vous pouvez répéter ces opérations autant que fois que vous le voulez, il suffit de rajouter le symbole %[lettre] à chaque fois que vous souhaitez afficher la valeur d’une variable. Il n’y a aucune limite, voyez par exemple :
double flottant = 19.75;
int nombre = 10, nombre_2 = 0;
char lettre = 'a';
nombre_2 = nombre * 3;
printf("nombre = %d, nombre_2 = %d, flottant = %f, lettre = %c", nombre, nombre_2, flottant, lettre);
Amusez-vous à créer des variables et à en afficher la valeur pour voir si vous avez bien compris. Attention cependant, vous devez préciser la variable dont il faut afficher la valeur, sinon vous pouvez aller des valeurs fantaisistes au plantage du programme !
Le scoop du jour
modifierDevinez quoi, vous pouvez effectuer toutes sortes d’opérations à l’intérieur même de printf, comme des calculs par exemple. Quelques codes pour bien comprendre :
printf("%d | ", 1 + 2 * 3); /* Affiche « 7 » */
printf("%d | ", (1 + 2) * 3); /* Affiche « 9 » */
printf("%f | ", -1. + 2. * 4. / 3.); /* Affiche « 1.666667 » */
printf("%c", 'x'); /* Affiche « x » */
7 | 9 | 1.666667 | x
Faites bien attention à mettre le « . », dans le cas contraire, le résultat serait faussé. Nous pouvons faire sensiblement la même chose avec des variables :
int x = 42, y = 21;
printf("%d", x * y / 2);
441
Tabulations et compagnie
modifierAfin d’afficher une tabulation ou encore un retour à la ligne, on utilise un caractère d'échappement.
printf("La valeur de la variable\n\tx est : %f\n\ty = %d", x, y);
La valeur de la variable
x est : 42.424340
y = 1
'\n' et '\t' font partie de ces caractères. Voici un petit tableau qui en liste quelques-uns parmi les plus utilisés :
Caractère d’échappement | Signification |
---|---|
'\n' | Retour à la ligne |
'\t' | Tabulation horizontale |
'\r' | Retour chariot |
'\f' | Saut de page |
'\ | Affiche une apostrophe |
'\"' | Affiche un guillemet |
'\\' | Affiche un antislash |
'%%' | Affiche un % |
Précision
modifierSi vous avez été attentifs, vous avez dû remarquer que lorsqu'on affiche un flottant il y a un certain nombre de zéros qui suivent, et ce peu importe s'ils sont utiles ou non. Heureusement, les programmeurs de la fonction printf ont pensé à tout. Afin de supprimer certains zéros inutiles, vous pouvez préciser la précision de l’affichage. Une précision, sous la forme d’un point ('.') suivi par un nombre, indique donc le nombre de chiffres qu’il y aura derrière la virgule.
double x = 42.42734;
printf("%.2f", x);
42.43
On remarque dans cet exemple un arrondi au centième. Il correspond au nombre indiqué lors de la précision de l'affichage. La variable n'a pas été modifiée, l'arrondi n'intervient que pour l'affichage.
Pour finir, voici la chaîne de format (simplifiée) qu’utilise la fonction printf :
% [.précision] indicateur de conversion
Sur plusieurs lignes
modifierPlutôt qu'appeler plusieurs fois la fonction printf pour écrire du texte, on peut ne l'appeler qu'une fois et écrire plusieurs lignes. Pour cela, on utilise le signe \ à chaque fin de ligne. Exemple :
#include <stdio.h>
int main(void)
{
printf("Texte ecrit sur plusieurs \
lignes dans le code source \
et également dans la console");
return 0;
}
Texte ecrit sur plusieurs lignes dans le code source
et également dans la console
L'inconvénient est que le texte affiché dans la console n’est pas parfaitement alignés. Il existe heureusement une autre possibilité : on peut écrire plusieurs phrases entre guillemets sans problème :
#include <stdio.h>
int main(void)
{
printf("Texte ecrit sur plusieurs "
"lignes dans le code source "
"mais sur une seule dans la console");
return 0;
}
Texte ecrit sur plusieurs lignes dans le code source mais sur une seule dans la console
Ce qu’il faut retenir de ces deux méthodes, c’est que l’on est pas obligé d'appeler systématiquement printf / puts pour afficher de nouvelles phrases, mais qu'au contraire il est possible d’en afficher plusieurs en n'utilisant qu'une fois la fonction.
puts — Écrire une chaîne de caractères
modifierL’utilisation de la fonction puts est plus simple puisqu’elle ne se contente d'afficher que des chaînes de caractères simples.
puts("Salut les zeros !");
Cette fonction n’a pas de chaîne de format à évaluer comme printf, elle est donc plus simple à utiliser ainsi que (très légèrement) plus rapide à l’exécution. Ainsi, le code suivant ne fonctionnera pas :
int var = 0;
puts("%d", var);
Je tiens à préciser que puts ajoute automatiquement une fin de ligne à la fin de la chaîne de caractères que vous souhaitez afficher.
putchar — Écrire un caractère
modifierLa fonction putchar affiche tout simplement un caractère.
putchar('c');
On peut également afficher une variable de type char avec cette fonction.
char caractere = 'Z';
putchar(caractere);
On initialise la variable caractere avec la lettre 'Z' puis on l’affiche.
Interagir avec l’utilisateur
modifierMaintenant que nous savons déclarer, utiliser et même afficher des variables, nous sommes fin prêts pour interagir avec l’utilisateur. En effet, jusqu’à maintenant, on s’est contentés d’afficher des informations. Nous allons voir comment en récupérer grâce à la fonction scanf, dont l’utilisation est assez semblable à printf.
scanf("%[lettre]", &variable_dans_laquelle_on_va_mettre_notre_valeur);
Souvenez-vous de la brève explication sur la mémoire au début du chapitre précédent. Celle-ci, je vous le rappelle, fonctionne comme une armoire avec des tiroirs (les adresses mémoires) et des objets dans ces tiroirs (nos variables). La fonction scanf a besoin de connaitre l’emplacement en mémoire de nos variables afin de les modifier. Afin d’effectuer cette opération, on utilise le symbole &. Ce concept de transmission d’adresses mémoires est un petit peu difficile à comprendre au début, ne vous inquiétez pas ; vous aurez l’occasion de bien revoir tout cela en profondeur dans le chapitre des pointeurs.
Vous pouvez tester ce programme :
int age;
puts("Donnez votre age :");
scanf("%d", &age);
printf("Vous avez %d an(s) !\n", age);
Donnez votre age :
15
Vous avez {{unité|15|ans}}(s) !
Note : si vous oubliez le &, le programme plantera quand vous le lancerez, car vous tenterez d’accéder à une adresse mémoire inexistante !
Ici, scanf attend patiemment que l’utilisateur saisisse un nombre au clavier afin de modifier la valeur contenue à l’adresse de age : on dit que c’est une fonction bloquante, puisqu'elle suspend l'exécution du programme tant que l'utilisateur n'a rien rentré. Ensuite, printf affiche bien ce qui est voulu.
Les indicateurs de conversions sont peu différents de ceux de printf :
Type | Affichage | Exemple |
---|---|---|
char | %c | char lettre; scanf("%c", &lettre);
|
int | %d | int age; scanf("%d", &age);
|
long | %ld | long age; scanf("%ld", &age);
|
short | %hd | short age; scanf("%hd", &age);
|
float | %f | float taille; scanf("%f", &taille);
|
double | %lf | double taille; scanf("%lf", &taille);
|
long double | %Lf | long double taille; scanf("%Lf", &taille);
|
unsigned int | %u | unsigned int age; scanf("%u", &age);
|
unsigned long | %lu | unsigned long age; scanf("%u", &age);
|
unsigned short | %hu | unsigned short age; scanf("%u", &age);
|
Vous pouvez utiliser cette fonction de différentes manières, vous pouvez lire plusieurs entrées en même temps, par exemple :
int x, y;
scanf("%d %d", &x, &y);
printf("x = %d | y = %d\n", x, y);
L’utilisateur a deux possibilités, soit d’insérer un espace, soit d’insérer un retour à la ligne :
14
6
x = 14 | y = 6
### OU ENCORE ###
14 6
x = 14 | y = 6
La fonction scanf est en apparence simple, oui, je dis bien en apparence, car son utilisation peut devenir très complexe en sécurisant les entrées de l’utilisateur, par exemple. Cependant, à votre niveau, vous ne pouvez pas encore gérer le cas où l’utilisateur entre du texte à la place d’un nombre ; si cela arrive, votre programme aura de très fortes chances de planter. Ce n’est pas très grave, vous saurez en temps voulu comment gérer de manière avancée les entrées de l’utilisateur.
Exercice
modifierVous êtes prêts pour un exercice ? Essayez de coder une minicalculatrice qui :
- Dit bonjour ;
- Demande deux nombres entiers à l’utilisateur ;
- Les additionne, soustrait, multiplie et les divise (avec un arrondi au millième) ;
- Dit au revoir.
Au final, ce pourrait donner :
Bonjour !
Veuillez saisir le premier nombre : 4
Veuillez saisir le deuxième nombre : 7
Calculs :
4 + 7 = 11
4 - 7 = -3
4 * 7 = 28
4 / 7 = 0.571
Au revoir !
Essayez vraiment de réaliser ce petit programme sans aide, sans regarder le code de correction. Si besoin est, il est juste en dessous.
#include <stdio.h>
int main(void)
{
int nombre_1, nombre_2;
printf("Bonjour !\n\n");
/* On demande a l'utilisateur deux nombres */
printf("Veuillez saisir le premier nombre : ");
scanf("%d", &nombre_1);
printf("Veuillez saisir le deuxième nombre : ");
scanf("%d", &nombre_2);
/* Puis on effectue des calculs */
printf("\nCalculs :\n\n");
printf("\t%d + %d = %d\n", nombre_1, nombre_2, nombre_1 + nombre_2);
printf("\t%d - %d = %d\n", nombre_1, nombre_2, nombre_1 - nombre_2);
printf("\t%d * %d = %d\n", nombre_1, nombre_2, nombre_1 * nombre_2);
printf("\t%d / %d = %.3f\n", nombre_1, nombre_2, (double) nombre_1 / nombre_2);
printf("\nAu revoir !");
return 0;
}
Vous y êtes arrivé sans problème ? Bravo ! Dans le cas contraire, ne vous inquiétiez pas, ce n’est pas grave. Relisez bien tous les points qui ne vous semblent pas clairs et ça devrait aller mieux.
Maintenant, vous êtes capable de communiquer avec l’utilisateur. Cependant, nos actions sont encore un peu limitées. Nous verrons dans les prochains chapitres comment mieux réagir à ce que l’utilisateur communique.