Wie formatiere ich Strings mit printf (), um die gleiche Länge in der Ausgabe zu erhalten?

91

Ich habe zwei Funktionen, eine, die Nachrichten wie erzeugt, Starting initialization...und eine andere, die Rückkehrcodes und Ausgänge prüft "Ok", "Warning"oder "Error". Die erzeugte Ausgabe ist jedoch unterschiedlich lang:

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

Wie kann ich so etwas bekommen:

Starting initialization...       Ok.
Checking init scripts...         Ok.
Psihodelia
quelle

Antworten:

157

Sie können die Breite für Zeichenfolgenfelder angeben, z

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

und dann wird alles, was mit diesem Feld gedruckt wird, auf die von Ihnen angegebene Breite leer aufgefüllt.

Die -linke Seite rechtfertigt Ihren Text in diesem Feld.

Carl Smotricz
quelle
130
Leider bin ich nicht klug genug, um so hoch zu zählen. Ich vertraue jedoch darauf, dass der Fragesteller intelligent genug ist, um aus meinem Beispiel zu extrapolieren :)
Carl Smotricz
3
Was ist mit richtig gerechtfertigt? Es gibt keine Flaggen in K & R
Ungeheuer
9
Rechtsbündig ist die Standardeinstellung. Ohne a -werden Ihre Daten in einem Feld, dessen Breite Sie angegeben haben, richtig ausgerichtet.
Carl Smotricz
24

printfermöglicht die Formatierung mit Breitenangaben. z.B


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

Sie würden einen negativen Breitenbezeichner verwenden, um die Linksausrichtung anzuzeigen, da standardmäßig die Rechtsausrichtung verwendet wird.

PP.
quelle
18

Wenn Sie die Flexibilität wählen möchten width, können Sie außerdem zwischen einem der beiden folgenden Formate wählen (mit oder ohne Kürzung):

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."
Lebensbalance
quelle
13

Es gibt auch den %nModifikator, der unter bestimmten Umständen helfen kann. Es gibt die Spalte zurück, in der sich die Zeichenfolge bisher befand. Beispiel: Sie möchten wie eine Tabelle mehrere Zeilen schreiben, die innerhalb der Breite der ersten Zeile liegen.

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

gedruckt werden 2 Spalten mit derselben Breite , gleich welcher Länge die beiden Strings header1und header2haben kann. Ich weiß nicht, ob alle Implementierungen das haben, %naber Solaris und Linux.

Patrick Schlüter
quelle
Diese Lösung funktioniert, aber jeder, der dies übernimmt und in seinen Code einfügt, sollte sich des Risikos bewusst sein, Speicherschwachstellen einzuführen .
Matthew Cole
0

Es gibt auch die eher Low-Tech-Lösung, das Hinzufügen von Leerzeichen von Hand zu zählen, damit Ihre Nachrichten in einer Reihe stehen. Nichts hindert Sie daran, ein paar nachgestellte Leerzeichen in Ihre Nachrichtenzeichenfolgen aufzunehmen.

Carl Smotricz
quelle
-2

Beginnen Sie mit der Verwendung von Tabs, dem \ t- Zeichenmodifikator. Es wird an einen festen Ort vorgerückt (Spalten, Terminal-Jargon). Es hilft jedoch nicht, wenn es Unterschiede gibt, die größer als die Spaltenbreite sind (4 Zeichen, wenn ich mich richtig erinnere).

Um dies zu beheben, schreiben Sie Ihre "OK / NOK" -Stücke mit einer festen Anzahl von Registerkarten (5? 6?, Versuchen Sie es), kehren Sie dann ( \ r ) ohne neue Zeilen zurück und schreiben Sie Ihre Nachricht.

jpinto3912
quelle
5
Es besteht immer die Gefahr, dass eine Zeichenfolge länger als ein Tabulator ist, wodurch die resultierende Tabulatur und der Text falsch ausgerichtet werden.
PP.
Nicht wirklich ... schreibe zuerst die Registerkarte OK / NOK, dann / r, schreibe jetzt die Phrase, jetzt / n. Der Satz könnte das OK / NOK überschreiben. Aber dein Weg ist viel besser, ich wusste nichts über negative Rechtfertigung.
jpinto3912