Центрирование строк с помощью printf()
По умолчанию, printf()
, похоже, выравнивает строки справа.
printf("%10s %20s %20s\n", "col1", "col2", "col3");
/* col1 col2 col3 */
Я также могу выровнять текст влево:
printf("%-10s %-20s %-20s", "col1", "col2", "col3");
Есть ли быстрый способ централизовать текст? Или мне нужно написать функцию, которая превращает строку типа test
в (space)(space)test(space)(space)
, если ширина текста для этого столбца равна 8?
Ответы
Ответ 1
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;
}
Ответ 2
@GiuseppeGuerrini был полезен, предлагая, как использовать спецификаторы формата печати и разделяя пробел. К сожалению, он может усекать текст.
Следующее решает проблему усечения (при условии, что указанное поле на самом деле достаточно велико, чтобы вместить текст).
void centerText(char *text, int fieldWidth) {
int padlen = (fieldWidth - strlen(text)) / 2;
printf(%*s%s%*s\n", padLen, "", text, padlen, "");
}
Ответ 3
В центре текста нет спецификатора формата printf()
.
Вам нужно будет написать свою собственную функцию или найти библиотеку, которая предоставляет функциональные возможности, которые вы ищете.
Ответ 4
Вы можете попробовать написать собственную функцию для этой проблемы.
/**
* 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!!!
Ответ 5
Да, вам придется либо написать свою собственную функцию, которая возвращает "тест" и т.д., например.
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);
}
}
Ответ 6
Я потерял свои 2 цента после того, как столкнулся с похожей проблемой, связанной с попыткой центрировать заголовки таблицы подряд с помощью printf.
Следующие макросы необходимо будет напечатать до/после текста и выровнять независимо от длины самого текста. Обратите внимание, что если у нас есть строки нечетной длины, мы не выровняем как следует (потому что нормальное отклонение приведет к отсутствию пробела). Для этого требуется сводка, и я думаю, что это элегантный способ решить эту проблему:
#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"), "");
Ответ 7
Вы можете использовать один из двух следующих вариантов:
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 (центр)
Имя2 (в центре)