printf(3)
Fonction de la bibliothèque C
Écrit du texte mis en forme sur la sortie standard. Les formats à connaître (%d, %ld, %zu, %p, %s), ce que renvoie printf et les warnings -Wformat.
#include <stdio.h>
int printf(const char *restrict format, ...);Description
printf parcourt son format caractère par caractère. Le texte ordinaire est recopié tel quel ; chaque % introduit une conversion, qui consomme l'argument suivant et l'écrit sous forme de texte. Comme printf accepte un nombre variable d'arguments, il ne connaît pas leur type : c'est le format qui le lui dit, et il doit correspondre exactement.
| Format | Argument attendu |
|---|---|
%d ou %i | int |
%u, %x | unsigned int, en décimal ou en hexadécimal |
%ld, %lld | long, long long |
%zu | size_t, le type de sizeof et de strlen |
%f | double, ou un float, converti en double à l'appel |
%c | un caractère, transmis comme un int |
%s | un char * vers une chaîne terminée par '\0' |
%p | un void * |
%% | rien, affiche un % |
Le texte ne part pas directement à l'écran : il passe par le tampon de stdout, vidé à chaque \n dans un terminal et par blocs dans un pipe. C'est la raison pour laquelle printf n'affiche rien avant un crash.
Valeur de retour
Le nombre d'octets écrits, ou une valeur négative en cas d'erreur. Des octets, pas des caractères : dans un source en UTF-8, printf("été\n") renvoie 6, chaque « é » en occupant deux.
Pièges
Un format qui ne correspond pas au type est un comportement indéfini.
-Wallactive-Wformat, qui le détecte à la compilation. Pour unsizeof, GCC propose%ldparce quesize_test ununsigned longsur cette machine, mais%zuest la seule écriture portable :
$ gcc -Wall -Wextra -g warn.c -o warnwarn.c: In function 'main':warn.c:7:14: warning: format '%d' expects argument of type 'int', but argument 2 has type 'long unsigned int' [-Wformat=] 7 | printf("%d\n", sizeof notes); | ~^ ~~~~~~~~~~~~ | | | | int long unsigned int | %ldprintf(texte), quandtextevient de l'utilisateur, interprète chaque%qu'il contient, et%npermet même d'écrire en mémoire. Écrisprintf("%s", texte).%pattend unvoid *: convertis le pointeur,(void *)p.L'exercice fix-the-format te fait corriger un format faux sous
-Werror, avec unsize_tet unlong.
Exemple
#include <stdio.h>
int main(void){ int notes[5] = {12, 15, 9, 18, 11}; long total = 6000000000L; int n;
n = printf("Yasmine a %d ans\n", 19); printf("%d octets\n", n); n = printf("été\n"); printf("%d octets\n", n); printf("%zu octets à l'adresse %p\n", sizeof notes, (void *)notes); printf("total : %ld\n", total); return 0;}$ gcc -Wall -Wextra -g formats.c -o formats$ ./formatsYasmine a 19 ans17 octetsété6 octets20 octets à l'adresse 0xffffe6dfb940total : 6000000000Le \n compte dans les 17 octets de la première ligne. L'adresse change à chaque exécution.
mini_printf
Écris mini_printf, qui développe %c, %s, %d, %x et %% avec write et renvoie le nombre exact d'octets écrits.