Comment formater des chaînes en utilisant printf () pour obtenir une longueur égale dans la sortie?

92

J'ai deux fonctions, une qui produit des messages comme Starting initialization...et une autre qui vérifie les codes de retour et les sorties "Ok", "Warning"ou "Error". Cependant, la sortie produite est de longueur différente:

Starting initialization...Ok.
Checking init scripts...Ok.

Comment puis-je obtenir quelque chose comme ça:

Starting initialization...       Ok.
Checking init scripts...         Ok.
psihodelia
la source

Réponses:

159

Vous pouvez spécifier la largeur sur les champs de chaîne, par exemple

printf("%-20s", "initialization...");

et tout ce qui est imprimé avec ce champ sera rempli de blanc à la largeur que vous indiquez.

La -gauche justifie votre texte dans ce champ.

Carl Smotricz
la source
130
Hélas, je ne suis pas assez intelligent pour compter aussi haut. Cependant, je fais confiance au demandeur pour être assez intelligent pour extrapoler à partir de mon exemple :)
Carl Smotricz
3
qu'en est-il juste justifié? Il n'y a pas de drapeaux mentionnés dans K&R
Ungeheuer
9
La justification à droite est la valeur par défaut. Sans a -, vos données seront justifiées à droite dans un champ dont vous avez spécifié la largeur.
Carl Smotricz
24

printfpermet le formatage avec des spécificateurs de largeur. par exemple


printf( "%-30s %s\n", "Starting initialization...", "Ok." );

Vous utiliseriez un spécificateur de largeur négatif pour indiquer la justification à gauche car la valeur par défaut est d'utiliser la justification à droite.

PP.
la source
18

De plus, si vous souhaitez avoir la widthpossibilité de choisir le , vous pouvez choisir entre l'un des deux formats suivants (avec ou sans troncature):

int width = 30;
//no truncation uses %-*s
printf( "%-*s %s\n", width, "Starting initialization...", "Ok." );
// output is "Starting initialization...     Ok."

//truncated to the specified width uses %-.*s
printf( "%-.*s %s\n", width, "Starting initialization...", "Ok." ); 
// output is "Starting initialization... Ok."
équilibre de vie
la source
13

Il y a aussi le %nmodificateur qui peut aider dans certaines circonstances. Il renvoie la colonne sur laquelle la chaîne se trouvait jusqu'ici. Exemple: vous voulez écrire plusieurs lignes dans la largeur de la première ligne comme un tableau.

int width1, width2;
int values[6][2];
printf("|%s%n|%s%n|\n", header1, &width1, header2, &width2);

for(i=0; i<6; i++)
   printf("|%*d|%*d|\n", width1, values[i][0], width2, values[i][1]);

imprimera 2 colonnes de la même largeur de longueur quelle que soit les deux chaînes header1et header2peut avoir. Je ne sais pas si toutes les implémentations ont le %nmais Solaris et Linux le font.

Patrick Schlüter
la source
Cette solution fonctionne, mais toute personne qui la prend et la met dans son code doit être conscient du risque d'introduire des vulnérabilités de mémoire .
Matthew Cole
0

Il y a aussi la solution plutôt low-tech de compter en ajoutant des espaces à la main pour aligner vos messages. Rien ne vous empêche d'inclure quelques espaces de fin dans vos chaînes de message.

Carl Smotricz
la source
-2

Commencez par utiliser les tabulations, le modificateur de caractères \ t . Il avancera vers un emplacement fixe (colonnes, jargon terminal). Cependant, cela n'aide pas s'il y a des différences supérieures à la largeur de la colonne (4 caractères, si je me souviens bien).

Pour résoudre ce problème, écrivez votre truc "OK / NOK" en utilisant un nombre fixe d'onglets (5? 6 ?, essayez-le), puis retournez ( \ r ) sans nouvelle ligne, et écrivez votre message.

jpinto3912
la source
5
Il y a toujours le risque qu'une chaîne soit plus longue qu'un taquet de tabulation, forçant ainsi la tabulation et le texte résultants à être mal alignés.
PP.
Pas vraiment ... écrivez d'abord l'onglet OK / NOK, puis / r, écrivez maintenant la phrase, maintenant / n. La phrase pourrait remplacer le OK / NOK. Mais votre chemin est bien meilleur, je ne connaissais pas la justification négative.
jpinto3912