wake-up-neo.net

Zeichenketten mit printf () zentrieren

Standardmäßig scheint printf() die Zeichenfolgen nach rechts auszurichten.

printf("%10s %20s %20s\n", "col1", "col2", "col3");
/*       col1                 col2                 col3 */

Ich kann den Text auch so nach links ausrichten:

printf("%-10s %-20s %-20s", "col1", "col2", "col3");

Gibt es eine schnelle Möglichkeit, Text zu zentrieren? Oder muss ich eine Funktion schreiben, die eine Zeichenfolge wie test in (space)(space)test(space)(space) umwandelt, wenn die Textbreite für diese Spalte 8 ist?

20
Pieter

printf alleine kann den Trick nicht machen, aber Sie könnten mit der "indirekten" Breite spielen, die die Breite angibt, indem Sie sie aus einem Argument lesen. Lass 'es versuchen (ok, nicht perfekt)

void f(char *s)
{
        printf("---%*s%*s---\n",10+strlen(s)/2,s,10-strlen(s)/2,"");
}
int main(int argc, char **argv)
{
        f("uno");
        f("quattro");
        return 0;
}
28

@ GiuseppeGuerrini's war hilfreich, indem vorgeschlagen wurde, wie Druckformat-Bezeichner verwendet werden sollen, und das Leerzeichen aufgeteilt wird. Leider kann Text abgeschnitten werden.

Im Folgenden wird das Problem der Abschneidung gelöst (vorausgesetzt, das angegebene Feld ist tatsächlich groß genug, um den Text aufzunehmen). 

void centerText(char *text, int fieldWidth) {
    int padlen = (fieldWidth - strlen(text)) / 2;
    printf(%*s%s%*s\n", padLen, "", text, padlen, "");
} 
4
clearlight

Es gibt keinen printf()-Formatbezeichner, um den Text zu zentrieren.

Sie müssen eine eigene Funktion schreiben oder eine Bibliothek suchen, die die gewünschte Funktionalität bereitstellt.

1
Convict

Sie können versuchen, eine eigene Funktion für dieses Problem zu schreiben.

/**
 * Returns a sting "str" centered in string of a length width "new_length".
 * Padding is done using the specified fill character "placeholder".
 */
char *
str_center(char str[], unsigned int new_length, char placeholder)
{
    size_t str_length = strlen(str);

    // if a new length is less or equal length of the original string, returns the original string
    if (new_length <= str_length)
        return str;

    char *buffer;
    unsigned int i, total_rest_length;

    buffer = malloc(sizeof(char) * new_length);

    // length of a wrapper of the original string
    total_rest_length = new_length - str_length;

    // write a prefix to buffer
    i = 0;
    while (i < (total_rest_length / 2)) {
        buffer[i] = placeholder;
        ++i;
    }
    buffer[i + 1] = '\0';

    // write the original string
    strcat(buffer, str);

    // write a postfix to the buffer
    i += str_length;
    while (i < new_length) {
        buffer[i] = placeholder;
        ++i;
    }
    buffer[i + 1] = '\0';

    return buffer;
}

Ergebnisse:

puts(str_center("A", 0, '-')); // A
puts(str_center("A", 1, '-')); // A
puts(str_center("A", 10, '-')); // ----A-----
puts(str_center("text", 10, '*')); // ***text***
puts(str_center("The C programming language", 26, '!')); // The C programming language
puts(str_center("The C programming language", 27, '!')); // The C programming language!
puts(str_center("The C programming language", 28, '!')); // !The C programming language!
puts(str_center("The C programming language", 29, '!')); // !The C programming language!!
puts(str_center("The C programming language", 30, '!')); // !!The C programming language!!
puts(str_center("The C programming language", 31, '!')); // !!The C programming language!!!
1
Seti Volkylany

Ich werde meine 2 Cent fallen lassen, nachdem ich mich mit dem ähnlichen Problem des Versuchs befasst hatte, Tabellenköpfe in einer Reihe mit printf zu zentrieren.

Die folgenden Makros müssen vor/nach dem Text gedruckt werden und werden unabhängig von der Länge des Textes selbst ausgerichtet. Beachten Sie, dass bei ungeraden Längenfolgen keine Ausrichtung erfolgt, da dies zu einer normalen Unterteilung führt in den fehlenden Räumen) . Dafür ist eine Zusammenfassung erforderlich, und ich denke, das ist die elegante Art, dieses Problem zu lösen:

#define CALC_CENTER_POSITION_PREV(WIDTH, STR) (((WIDTH + ((int)strlen(STR))) % 2) \
       ? ((WIDTH + ((int)strlen(STR)) + 1)/2) : ((WIDTH + ((int)strlen(STR)))/2))
#define CALC_CENTER_POSITION_POST(WIDTH, STR) (((WIDTH - ((int)strlen(STR))) % 2) \
       ? ((WIDTH - ((int)strlen(STR)) - 1)/2) : ((WIDTH - ((int)strlen(STR)))/2))

Anwendungsbeispiel:

printf("%*s%*s" , CALC_CENTER_POSITION_PREV(MY_COLUMN_WIDTH, "Header")
                , "Header"
                , CALC_CENTER_POSITION_POST(MY_COLUMN_WIDTH, "Header"), "");
0
Sielar

Ja, Sie müssen entweder eine eigene Funktion schreiben, die "test" usw. zurückgibt, z.

printf("%s %s %s", center("col1", 10), center("col2", 20), center("col3", 20));

Oder Sie haben eine center_print-Funktion, etwa wie folgt:

void center_print(const char *s, int width)
{
        int length = strlen(s);
        int i;
        for (i=0; i<=(width-length)/2; i++) {
                fputs(" ", stdout);
        }
        fputs(s, stdout);
        i += length;
        for (; i<=width; i++) {
                fputs(" ", stdout);
        }
}
0
hlovdal