2009-01-16 6 views
8

A partir de maintenant je suis en utilisant la ligne ci-dessous pour imprimer avec des points deComment imprimer un tiret ou un point en utilisant fprintf/printf?

fprintf(stdout, "%-40s[%d]", tag, data); 

Je me attends à la sortie serait quelque chose comme suit,

 
Number of cards..................................[500] 
Fixed prize amount [in whole dollars]............[10] 
Is this a high winner prize?.....................[yes] 

Comment imprimer tiret ou point à l'aide fprintf/printf?

Répondre

10

Une approche plus rapide:

Si le montant maximum de rembourrage que vous aurez jamais Le besoin est connu à l'avance (ce qui est normalement le cas lorsque vous formatez une table de largeur fixe comme celle que vous avez), vous pouvez utiliser une chaîne statique de "padder" et en extraire un morceau. Ce sera plus rapide que d'appeler printf ou cout dans une boucle.

static const char padder[] = "......................"; // Many chars 

size_t title_len = strlen(title); 
size_t pad_amount = sizeof(padder) - 1 - title_len; 

printf(title); // Output title 

if (pad_amount > 0) { 
    printf(padder + title_len); // Chop! 
} 

printf("[%d]", data); 

Vous pouvez même le faire dans une déclaration, avec un certain acte de foi:

printf("%s%s[%d]", title, padder + strlen(title), data); 
+0

votre dernière suggestion casse si 'strlen (titre)> strlen (padder)' – Christoph

+0

@Christoph, d'où le proclamé "acte de foi" :) –

+0

@Ates: concept intéressant, cette 'programmation fidèle' de la vôtre;) – Christoph

2

Vous allez devoir sortir la chaîne avec le remplissage de point ou de tableau de bord vous-même.

Quelque chose comme (pardonnez mon C, il est rouillé):

printAmount(char *txt, int amt) { 
    printf("%s",txt); 
    for(int xa=strlen(txt); xa<40; xa++) { putc('.'); } 
    printf("[%d]",amt); 
    printf("\n"); 
    } 
3

Vous ne pouvez pas le faire dans une déclaration. Vous pouvez utiliser sprintf, puis remplacer les points pour les espaces vous-même, ou faire quelque chose comme

int chars_so_far; 
char padder[40+1]= '..........'; //assume this is 40 dots. 
printf("%.40s%n",tag,&chars_so_far); 
printf("%s[%d]",padder+chars_so_far,data); 

Edit: simplifié mon exemple ci-dessus basé sur le concept de padder @Ates. De cette façon, il n'y a pas de 'sauts de confiance', que la chaîne soit trop grande ou trop petite - elle commence toujours les données dans la colonne 41.

+0

Je pense que cela peut être fait dans une déclaration. –

+0

@Ates: il pourrait, mais je ne suis pas sans deux appels à 'strlen()' si vous voulez vérifier correctement les limites - par conséquent, vous devez mettre en cache cette valeur -> deux déclarations! – Christoph

1

Je suggère d'écrire une fonction qui remplit une chaîne avec X caractères et l'utiliser pour générer le premier argument à votre chaîne printf. Quelque chose comme:

char s[40]; 
pad_str(tag, s, 40, '.'); 
fprintf(stdout, "%-40s[%d]", s, data); 

Notez que la troisième ligne de vos données d'échantillon aurait besoin de ce format:

"%-40s[%s]" 
2

Une autre solution à l'aide d'une petite fonction d'aide

static inline size_t min(size_t a, size_t b) 
{ 
    return a < b ? a : b; 
} 

Ensuite, vous pouvez faire ce qui suit :

char padder[] = "........................................"; 
int len = min(strlen(tag), sizeof(padder) - 1); 
printf("%.*s%s[%d]", len, tag, padder + len, data); 

C'est essentiellement ce Ates affiché, mais je fait compris cela moi-même;)

+0

Change the size_t en int; vous devez passer un int au '*' dans la famille de fonctions printf(). –

+0

Ou rendre l'assistant plus utile: printf ("% s% s [% d]", titre, getPadding (titre), données); –

+0

@Jonathan: merci, corrigé ... – Christoph

9

Vous pouvez facilement le faire avec iostreams au lieu de printf

cout << setw(40) << setfill('.') << left << tag[i] << '[' << data[i] << ']' << endl; 

Ou si vous avez vraiment besoin d'utiliser fprintf (par exemple, vous êtes passé un FICHIER * à écrire à)

strstream str; 
str << setw(40) << setfill('.') << left << tag[i] << '[' << data[i] << ']' << endl; 
printf(%s", str.str()); 
+0

+1 pour être facile à lire et à comprendre et ne pas casser sous certaines (quoique des situations assez rares). –

0

Je pense qu'il y a un meilleur moyen.

#include <string.h> 
#include <stdio.h> 

#define MIN(A,B) ((A)<(B)?(A):(B)) 
char *dashpad(char *buf, int len, const char *instr) { 
    memset(buf, '-', len); 
    buf[len] = 0; 
    int inlen = strlen(instr); 
    memcpy(buf, instr, MIN(len, inlen)); 
    return buf; 
} 
main() { 
    char buf[40]; 
    printf("%s\n", dashpad(buf, 40, "Hello world, dash padded ")); 
} 
+0

Tout d'abord remplir le tampon entier avec le caractère pad, puis en les écrasant semble un peu inutile ... –

+0

En outre, vous avez un dépassement de tampon (n'aimez-vous pas C) - s/be: buf [len-1 ] = 0; –

+0

Et vous avez un bug null-erasure dans min(), qui devrait aussi être len-1. –

Questions connexes