web-dev-qa-db-ja.com

printf()による文字列の中央揃え

デフォルトでは、printf()は文字列を右に揃えるようです。

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

次のようにテキストを左に揃えることもできます。

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

テキストを中央に配置する簡単な方法はありますか?または、その列のテキスト幅が8の場合、testなどの文字列を(space)(space)test(space)(space)に変換する関数を作成する必要がありますか?

23
Pieter

printf自体はトリックを実行できませんが、引数から幅を指定する「間接」幅で遊ぶことができます。これを試してみましょう(OK、完璧ではありません)

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;
}
29

@GiuseppeGuerriniは、印刷形式指定子の使用方法を提案し、空白を分割することで役に立ちました。残念ながら、テキストを切り捨てることができます。

以下は、切り捨ての問題を解決します(指定されたフィールドが実際にテキストを保持するのに十分大きいと仮定します)。

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

テキストを中央に配置するprintf()形式指定子はありません。

独自の関数を記述するか、探している機能を提供するライブラリを見つける必要があります。

2
Convict

この問題に対して独自の関数を作成してみてください。

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

結果:

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!!!
2
Seti Volkylany

Printfを使用してテーブルヘッダーを行の中央に配置しようとする同様の問題を処理した後、2セントを失います。

次のマクロは、テキストの前後に印刷する必要があり、テキスト自体の長さに関係なく整列します。奇数の長さの文字列がある場合、本来のように整列しないことに注意してください(通常の分割ではスペースが失われるため)。したがって、切り上げが必要であり、これはその問題を解決するエレガントな方法だと思います:

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

使用例:

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

はい、「test」などを返す独自の関数を作成する必要があります。

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

または、次のようなcenter_print関数があります。

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