• Aucun résultat trouvé

int main() /* Plus petit programme C/C++. */

{

return 0;

}

La fonctionmaindoit renvoyer un code d’erreur d’exécution du programme, le type de ce code est int. Elle peut aussi recevoir des paramètres du système d’exploitation. Ceci sera expliqué plus loin.

Pour l’instant, on se contentera d’une fonction main ne prenant pas de paramètre.

Note : Il est spécifié dans la norme du C++ que la fonctionmainne doit pas renvoyer le type void.

En pratique cependant, beaucoup de compilateurs l’acceptent également.

La valeur0retournée par la fonctionmainindique que tout s’est déroulé correctement. En réalité, la valeur du code de retour peut être interprétée différemment selon le système d’exploitation utilisé. La bibliothèque C définit donc les constantesEXIT_SUCCESSetEXIT_FAILURE, qui perme-ttent de supprimer l’hypothèse sur la valeur à utiliser respectivement en cas de succès et en cas d’erreur.

1.8. Les fonctions d’entrée / sortie de base

Nous avons distingué au début de ce chapitre les programmes graphiques, qui traitent les événements qu’ils reçoivent du système sous la forme de messages, des autres programmes, qui reçoivent les données à traiter et écrivent leurs résultats sur les flux d’entrée / sortie standards. Les notions de flux d’entrée / sortie standards n’ont pas été définies plus en détail à ce moment, et il est temps à présent de pallier cette lacune.

1.8.1. Généralités sur les flux d’entrée / sortie en C

Un flux est une notion informatique qui permet de représenter un flot de données séquentielles en provenance d’une source de données ou à destination d’une autre partie du système. Les flux sont utilisés pour uniformiser la manière dont les programmes travaillent avec les données, et donc pour simplifier leur programmation. Les fichiers constituent un bon exemple de flux, mais ce n’est pas le seul type de flux existant : on peut traiter un flux de données provenant d’un réseau, d’un tampon mémoire ou de toute autre source de données ou partie du système permettant de traiter les données séquentiellement.

Sur quasiment tous les systèmes d’exploitation, les programmes disposent dès leur lancement de trois flux d’entrée / sortie standards. Généralement, le flux d’entrée standard est associé au flux de données provenant d’un terminal, et le flux de sortie standard à la console de ce terminal. Ainsi, les données que l’utilisateur saisit au clavier peuvent être lues par les programmes sur leur flux d’entrée standard,

Chapitre 1. Première approche du C/C++

et ils peuvent afficher leurs résultats à l’écran en écrivant simplement sur leur flux de sortie standard.

Le troisième flux standard est le flux d’erreur standard qui, par défaut, est également associé à l’écran, et sur lequel le programme peut écrire tous les messages d’erreur qu’il désire.

Note : La plupart des systèmes permettent de rediriger les flux standards des programmes afin de les faire travailler sur des données provenant d’une autre source de données que le clavier, ou, par exemple, de leur faire enregistrer leurs résultats dans un fichier. Il est même courant de réaliser des « pipelines » de programmes, où les résultats de l’un sont envoyés dans le flux d’entrée standard de l’autre, et ainsi de suite. Ces suites de programmes sont également appelés des tubes en français.

La manière de réaliser les redirections des flux standards dépend des systèmes d’exploitation et de leurs interfaces utilisateurs. De plus, les programmes doivent être capables de travailler avec leurs flux d’entrée / sortie standards de manière générique, que ceux-ci soient redirigés ou non.

Les techniques de redirection ne seront donc pas décrites plus en détail ici.

Vous remarquerez l’intérêt d’avoir deux flux distincts pour les résultats des programmes et leurs messages d’erreur. Si, lors d’une utilisation normale, ces deux flux se mélangent à l’écran, ce n’est pas le cas lorsque l’on redirige le flux de sortie standard. Seul le flux d’erreur standard est affiché à l’écran dans ce cas, et les messages d’erreur ne se mélangent donc pas aux résultats du programme.

On pourrait penser que les programmes graphiques ne disposent pas de flux d’entrée / sor-tie standards. Pourtant, c’est généralement le cas. Les événements traités par les programmes graphiques dans leur boucle de messages ne proviennent généralement pas du flux d’entrée standard, mais d’une autre source de données spécifique à chaque système. En conséquence, les programmes graphiques peuvent toujours utiliser les flux d’entrée / sortie standard si cela s’avère nécessaire.

Afin de permettre aux programmes d’écrire sur leurs flux d’entrée / sortie standards, la bibliothèque C définit plusieurs fonctions extrêmement utiles. Les deux principales fonctions sont sans doute les fonctionsprintfetscanf. La fonctionprintf(« print formatted » en anglais) permet d’afficher des données à l’écran, etscanf(« scan formatted ») permet de les lire à partir du clavier.

En réalité, ces fonctions ne font rien d’autre que d’appeler deux autres fonctions permettant d’écrire et de lire des données sur un fichier : les fonctions fprintf etfscanf. Ces fonctions s’utilisent exactement de la même manière que les fonctionsprintfetscanf, à ceci près qu’elles prennent en premier paramètre une structure décrivant le fichier sur lequel elles travaillent. Pour les flux d’entrée / sortie standards, la bibliothèque C définit les pseudo-fichiersstdin,stdoutetstderr, qui corres-pondent respectivement aux flux d’entrée, au flux de sortie et au flux d’erreur standards. Ainsi, tout appel àscanfse traduit par un appel àfscanfsur le pseudo-fichierstdin, et tout appel àprintf par un appel àfprintfsur le pseudo-fichierstdout.

Note : Il n’existe pas de fonction permettant d’écrire directement sur le flux d’erreur standard.

Par conséquent, pour effectuer de telles écritures, il faut impérativement passer par la fonction fprintf, en lui fournissant en paramètre le pseudo-fichierstderr.

La description des fonctions de la bibliothèque C standard dépasse de loin le cadre de ce cours.

Aussi les fonctions de lecture et d’écriture sur les fichiers ne seront-elles pas décrites plus en détail ici. Seules les fonctionsprintfetscanfseront présentées, car elles sont réellement in-dispensable pour l’écriture d’un programme C. Consultez la bibliographie si vous désirez obtenir plus de détails sur la bibliothèque C et sur toutes les fonctions qu’elle contient.

Le C++ dispose également de mécanismes de gestion des flux d’entrée / sortie qui lui sont propres. Ces mécanismes permettent de contrôler plus finement les types des données écrites et lues de et à partir des flux d’entrée / sortie standards. De plus, ils permettent de réaliser les opérations d’écriture et de lecture des données formatées de manière beaucoup plus simple.

Chapitre 1. Première approche du C/C++

Cependant, ces mécanismes requièrent des notions objets avancées et ne seront décrits que dans les chapitres dédiés au C++. Comme il est également possible d’utiliser les fonctionsprintf etscanfen C++ d’une part, et que, d’autre part, ces fonctions sont essentielles en C, la suite de cette section s’attachera à leur description. Un chapitre complet est dédié aux mécanismes de gestion des flux du C++ dans la deuxième partie de ce document.

Les fonctions printfetscanf sont toutes deux des fonctions à nombre de paramètres variables.

Elles peuvent donc être utilisées pour effectuer des écritures et des lectures multiples en un seul appel.

Afin de leur permettre de déterminer la nature des données passées dans les arguments variables, elles attendent toutes les deux en premier paramètre une chaîne de caractères descriptive des arguments suivants. Cette chaîne est appelée chaîne de format, et elle permet de spécifier avec précision le type, la position et les options de format (précision, etc.) des données à traiter. Les deux sections suivantes décrivent la manière d’utiliser ces chaînes de format pour chacune des deux fonctions printf et scanf.

1.8.2. La fonction printf

La fonctionprintfs’emploie comme suit :

printf(chaîne de format [, valeur [, valeur [...]]])

On peut passer autant de valeurs que l’on veut, pour peu qu’elles soient toutes référencées dans la chaîne de format. Elle renvoie le nombre de caractères affichés.

La chaîne de format peut contenir du texte, mais surtout elle doit contenir autant de formateurs que de variables à afficher. Si ce n’est pas le cas, le programme plantera. Les formateurs sont placés dans le texte là où les valeurs des variables doivent être affichées.

La syntaxe des formateurs est la suivante :

%[[indicateur]...][largeur][.précision][taille] type

Un formateur commence donc toujours par le caractère %. Pour afficher ce caractère sans faire un formateur, il faut le dédoubler (%%).

Le type de la variable à afficher est obligatoire lui aussi. Les types utilisables sont les suivants : Tableau 1-1. Types pour les chaînes de format deprintf

Type de donnée à afficher Caractère de formatage

Numériques Entier décimal signé d

Entier décimal non signé u ou i

Entier octal non signé o

Entier hexadécimal non signé x (avec les caractères ’a’ à ’f’) ou X (avec les caractères ’A’ à ’F’) Flottants de type double f, e, g, E ou G

Caractères Caractère isolé c

Chaîne de caractères s

Chapitre 1. Première approche du C/C++

Type de donnée à afficher Caractère de formatage

Pointeurs Pointeur p

Note : Voir le Chapitre 4 pour plus de détails sur les pointeurs. Le format des pointeurs dépend de la machine.

Les valeurs flottantes infinies sont remplacées par les mentions+INFet-INF. Un non-nombre IEEE (Not-A-Number) donne+NANou-NAN. Notez que le standard C ne permet de formater que des valeurs de type double. Les valeurs flottantes de type float devront donc être convertie en double avant affichage.

Les autres paramètres sont facultatifs.

Les valeurs disponibles pour le paramètre de taille sont les caractères suivants : Tableau 1-2. Options pour les types des chaînes de format

Option Type utilisable Taille du type

F Pointeur Pointeur FAR (DOS uniquement)

N Pointeur Pointeur NEAR (DOS uniquement)

h Entier short int

l Entier, caractère ou chaîne

de caractères

long int ou wchar_t

L Flottant long double