使用printf()居中字符串

时间:2010-03-17 11:06:25

标签: c 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)的函数?

8 个答案:

答案 0 :(得分:28)

printf本身不能做到这一点,但你可以使用“间接”宽度,它通过从参数中读取宽度来指定宽度。让我们试试这个(好吧,不完美)

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

答案 1 :(得分:5)

@GiuseppeGuerrini的建议,通过建议如何使用打印格式说明符并分隔空格来提供帮助。不幸的是,它可以截断文本。

以下内容解决了截断问题(假设指定的字段实际上足够大以容纳文本)。

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

答案 2 :(得分:1)

没有printf()格式说明符来居中文本。

您需要编写自己的函数或找到提供您正在寻找的功能的库。

答案 3 :(得分:1)

您可以尝试为此问题编写自己的函数。

/**
 * 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!!!

答案 4 :(得分:0)

是的,你要么必须编写自己的函数来返回“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);
        }
}

答案 5 :(得分:0)

在处理类似的尝试将表头与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"), "");

答案 6 :(得分:0)

上面PADYMKO函数的一个更紧凑的版本(仍然会泄漏内存):

char *str_center(char str[], unsigned int new_length, char placeholder)
{
    size_t str_length = strlen(str);
    char *buffer;
    /*------------------------------------------------------------------
     * If a new length is less or equal length of the original string, 
     * returns the original string 
     *------------------------------------------------------------------*/
    if (new_length <= str_length)
    {
        return(str);
    }
    buffer = malloc(sizeof(char) * (new_length + 1));
    memset(buffer, placeholder, new_length);
    buffer[new_length] = '\0';
    bcopy(str, buffer + (( new_length - str_length) / 2), str_length);
    return(buffer);
}

这将整个新分配的缓冲区设置为填充字符,null 终止该字符,然后将要居中的字符串放到缓冲区的中间——没有循环,或者跟踪复制到的位置..

>

答案 7 :(得分:-2)

您可以使用以下两个选项之一:

char name[] = "Name1";

//Option One
printf("%*s", 40+strlen(name)/2, name, 40-strlen(name)/2, "");
puts("");//skip one line
//Option two
printf("%*s", 40+strlen("Name2")/2, "Name2", 40-strlen("Name2")/2, "");

输出结果为:

名1(中心)
NAME2(中心)