C 使用printf()对中字符串

C 使用printf()对中字符串,c,printf,C,Printf,默认情况下,printf()似乎将字符串向右对齐 printf("%10s %20s %20s\n", "col1", "col2", "col3"); /* col1 col2 col3 */ 我还可以将文本向左对齐,如下所示: printf("%-10s %-20s %-20s", "col1", "col2", "col3"); 有没有一种快速的方法将文本居中?或者,如果该列的文本宽度为8,我是否必须编写一个函

默认情况下,
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)

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


您需要编写自己的函数或找到一个提供所需功能的库。

是的,您必须编写自己的函数,返回“test”等,例如

printf("%s %s %s", center("col1", 10), center("col2", 20), center("col3", 20));
或者您有一个中心打印功能,类似于以下内容:

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);
        }
}
void center\u打印(常量字符*s,整数宽度)
{
整数长度=strlen(s);
int i;

for(i=0;iprintf本身无法实现这一点,但您可以使用“间接”宽度,它通过从参数中读取宽度来指定宽度。让我们试试这个(好的,不完美)


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

char name[] = "Name1";

//Option One
printf("%*s", 40+strlen(name)/2, name, 40-strlen(name)/2, "");
puts("");//skip one line
输出为:

名称1(中间)

Name2(中间)

您可以尝试为这个问题编写自己的函数

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

@GiuseppeGuerrini的建议很有帮助,建议如何使用打印格式说明符并划分空白。不幸的是,它可以截断文本

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


在处理了试图用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"), "");

上述PADYMKO函数的更紧凑版本(仍然泄漏内存):

char*str_中心(char str[],无符号整数新长度,char占位符)
{
长度=strlen(str);
字符*缓冲区;
/*------------------------------------------------------------------
*如果新长度小于或等于原始字符串的长度,
*返回原始字符串
*------------------------------------------------------------------*/

if(new_length)第一个建议:如何在不泄漏内存的情况下执行此操作?如果您根据一些似乎不合理的条件预先分配了一些缓冲区(例如,一个printf的中心参数不超过20个,并且中心结果都不超过200字节),您可以让中心函数在每次调用时旋转缓冲区你有没有测试过格式说明符来适应它们。你甚至测试过这个吗?你有机会去额外的9码来提供解决方案,嗯?我用C++写的代码来测试这个,来创建表,它截断了有效的文本,我必须找出原因。我已经根据我是如何解决它提供了一个可供选择的答案。ed我警告说,该解决方案“不完美”,因为它包含硬编码常量。我的目标只是给出一个提示,您的解决方案完成了这个想法。很酷,从教育c的角度来看,它只是c/stdlib实现,但至少用
memcpy()
bcopy()替换前缀/后缀循环
并将malloc替换为alloca..ewwalloca在这种情况下不起作用,因为返回的字符串在该内存中-您不希望它在“str_center”返回点处被释放!但正如Martin指出的那样,这样做会泄漏内存。请注意,根据if
fieldWidth-str,结果总宽度会有所不同len(text)
是偶数或奇数添加的一个修改版本,它始终打印
字段宽度
字符(例如用于表格等)
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!!!
void centerText(char *text, int fieldWidth) {
    int padlen = (fieldWidth - strlen(text)) / 2;
    printf("%*s%s%*s\n", padLen, "", text, padlen, "");
} 
#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"), "");
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);
}