Centering strings with printf()

前端 未结 7 1180
挽巷
挽巷 2020-12-01 10:33

By default, printf() seems to align strings to the right.

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


        
相关标签:
7条回答
  • 2020-12-01 11:08

    Yes, you will either have to write your own function that returns " test " etc, e.g.

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

    Or you have a center_print function, something like the following:

    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 讨论(0)
  • 2020-12-01 11:12

    There is no printf() format specifier to centre text.

    You will need to write your own function or locate a library which provides the functionality that you're looking for.

    0 讨论(0)
  • 2020-12-01 11:18

    @GiuseppeGuerrini's was helpful, by suggesting how to use print format specifiers and dividing the whitespace. Unfortunately, it can truncate text.

    The following solves the problem of truncation (assuming the field specified is actually large enough to hold the text).

    void centerText(char *text, int fieldWidth) {
        int padlen = (fieldWidth - strlen(text)) / 2;
        printf("%*s%s%*s\n", padLen, "", text, padlen, "");
    } 
    
    0 讨论(0)
  • 2020-12-01 11:25

    You may try write own function for this problem.

    /**
     * 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;
    }
    

    Results:

    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!!!
    
    0 讨论(0)
  • 2020-12-01 11:25

    Ill drop my 2 cents after dealing with similar issue of trying to center a table headers in a row with printf.

    The following macros will need to be printed before/after the text and will align regardless of the length of the text itself. Notice that if we have odd length strings, we will not align as should(because the normal devision will result in missing space). Therefor a round up is needed, and I think this is the elegant way to solve that issue:

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

    Usage example:

    printf("%*s%*s" , CALC_CENTER_POSITION_PREV(MY_COLUMN_WIDTH, "Header")
                    , "Header"
                    , CALC_CENTER_POSITION_POST(MY_COLUMN_WIDTH, "Header"), "");
    
    0 讨论(0)
  • 2020-12-01 11:31

    printf by itself can't do the trick, but you could play with the "indirect" width, which specifies the width by reading it from an argument. Lets' try this (ok, not perfect)

    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;
    }
    
    0 讨论(0)
提交回复
热议问题