2009-01-16 6 views
8

Ab sofort unterhalb der Linie Ich verwende mitWie drucke ich mit fprintf/printf einen Gedankenstrich oder einen Punkt?

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

aus dot drucken ich die Ausgabe etwas wie folgt wäre ich erwarten,

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

Wie Strich oder Punkt drucken Verwendung von fprintf/printf?

Antwort

10

Ein schneller Ansatz:

Wenn die maximale Menge an Polsterung, dass Sie jemals Notwendigkeit ist im Voraus bekannt (was normalerweise der Fall ist, wenn Sie eine Tabelle mit fester Breite wie die, die Sie haben, formatieren), können Sie eine statische "padder" Zeichenfolge verwenden und nur einen Brocken aus ihm greifen. Dies ist schneller als der Aufruf von printf oder cout in einer Schleife.

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); 

Man könnte sogar in einer Aussage tun, mit einem gewissen Sprung des Glaubens:

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

dein letzter Vorschlag bricht, wenn 'strlen (titel)> strlen (padder)' – Christoph

+0

@Christoph, folglich der proklamierte "Sprung des Glaubens" :) –

+0

@Ates: interessantes Konzept, dieses 'treue Programmieren von dir;) – Christoph

2

Sie müssen die Zeichenfolge mit dem Punkt- oder Strich-Padding selbst ausgeben.

So etwas wie (verzeihen Sie meine C, es ist rostig):

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

Sie nicht es in einer Erklärung tun. Sie können sprintf verwenden, dann Punkte für Räume ersetzen selbst, oder wie etwas tun

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: Vereinfachtes mein Beispiel oben basiert auf @Ates' Foulard-Konzept. Dieser Weg erfordert keine "Glaubenssprünge", ob die Tag-Zeichenkette zu groß oder zu klein ist - es startet immer die Daten in Spalte 41.

+0

Ich denke, dass es in einer Aussage getan werden kann. –

+0

@Ates: Es könnte, aber imo nicht ohne zwei Aufrufe von 'strlen()', wenn Sie Grenzen richtig überprüfen möchten - deshalb müssen Sie diesen Wert zwischenspeichern -> zwei Anweisungen! – Christoph

1

Ich würde vorschlagen, eine Funktion zu schreiben, die eine Zeichenkette mit auffüllt X-Zeichen und verwenden Sie das, um das erste Argument zu Ihrem printf String zu generieren. Etwas wie:

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

Beachten Sie, dass die dritte Zeile Ihrer Beispieldaten würden dieses Format benötigen:

"%-40s[%s]" 
2

Eine andere Lösung, die eine kleine Hilfsfunktion

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

Dann verwenden, können Sie folgendermaßen vorgehen :

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

Dies ist im Wesentlichen, was Ates geschrieben, aber ich dies tatsächlich auf meinem eigenen herausgefunden;)

+0

Ändern Sie die Größe_t in int; Sie müssen ein int an das '*' in der printf() - Familie von Funktionen übergeben. –

+0

Oder machen Sie den Helfer hilfreicher: printf ("% s% s [% d]", Titel, getPadding (Titel), Daten); –

+0

@ Jonathan: Danke, korrigierte es ... – Christoph

9

Sie können dies ganz einfach mit iostreams statt printf

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

Oder wenn Sie wirklich fprintf verwenden müssen (sagen wir, Sie sind eine Datei * zu schreiben, um zu schreiben)

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

+1 für leicht zu lesen und zu verstehen und nicht unter bestimmten (wenn auch etwas ungewöhnlichen Situationen) zu brechen. –

0

Ich denke, es gibt einen besseren Weg.

#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

Zuerst füllen Sie den gesamten Puffer mit dem Pad-Zeichen, und dann überschreiben sie scheint ein wenig verschwenderisch, obwohl ... –

+0

Auch haben Sie einen Puffer überschritten (nicht Sie lieben C) - s/be: buf [len-1 ] = 0; –

+0

Und du hast einen Null-Erase-Bug in dir min(), der auch len-1 sein sollte. –

Verwandte Themen