web-dev-qa-db-fra.com

chaîne printf, élément de longueur variable

#define SIZE 9
int number=5;
char letters[SIZE]; /* this wont be null-terminated */
... 

char fmt_string[20];
sprintf(fmt_string, "%%d %%%ds", SIZE);
/* fmt_string = "%d %9d"... or it should be */

printf(fmt_string, number, letters);

Y a-t-il une meilleure manière de faire cela?

38

Il n'est pas nécessaire de construire une chaîne de format spécial. printf vous permet de spécifier la précision à l'aide d'un paramètre (qui précède la valeur) si vous utilisez un .* comme précision dans la balise format.

Par exemple:

printf ("%d %.*s", number, SIZE, letters);

Remarque: il existe une distinction entre la largeur (qui est une largeur de champ minimale) et la précision (qui donne le nombre maximal de caractères à imprimer). %*s spécifie la largeur, %.s spécifie la précision. (et vous pouvez également utiliser %*.* mais alors vous avez besoin de deux paramètres, un pour la largeur, un pour la précision)

Voir aussi la page de manuel printf ( man 3 printf sous Linux) et surtout les sections sur la largeur et la précision des champs:

Au lieu d'une chaîne de chiffres décimaux, on peut écrire "*" ou "* m $" (pour un entier décimal m) pour spécifier que la précision est donnée dans l'argument suivant, ou dans le m-ème argument, respectivement, qui doit être de type int.

105
Trent

Une fonction quelque peu inconnue est asprintf . Le premier paramètre est un **char. Cette fonction aura malloc espace pour la chaîne afin que vous n'ayez pas à faire la comptabilité. N'oubliez pas de free la chaîne lorsque vous avez terminé.

char *fmt_string;

asprintf(&fmt_string, "%%d %%%ds", SIZE);
printf(fmt_string, number, letters);
free(fmt_string);

est un exemple d'utilisation.