Как выровнять вывод строки по центру в C
В языке C можно выводить данные с заданной фактической длиной, например для чисел это будет выглядеть так printf("|%5d|", 7); и вывод будет выглядеть так | 7|, так он равняет по правому краю, можно выровнять по левому краю, если поставить минус printf("|%-4d|", 7); будет так |7 |. А можно как-то выровнять по центру, чтобы было вот так | 7 | ?
Ответы (1 шт):
Из коробки printf так не умеет, придется писать что-то свое:
int
print_centered_string_to_stream(FILE *stream, const char *s, unsigned int width)
{
const size_t len = strlen(s);
/* If the length of the string is greater than the width
* just print the original string. */
if (len >= width)
return fprintf(stream, "%s", s);
/* Calculate the padding. */
const unsigned int p = (len >= width) ? 0 : (width - len) / 2;
return fprintf(stream, "%*.*s%s%*.*s", p, p, " ", s, p, p, " ");
}
Однако GNU C Library позволяет добавлять свои спецификаторы для printf. Ради интереса можно попробовать добавить свой спецификатор, который будет выводить строку по центру.
Для добавления нового спецификатора используется функция register_printf_specifier†. Мы должны передать ей три аргумента: сам символ спецификатора, функция вывода, и функция, которая даст printf информацию о типе аргументов:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <printf.h>
int
print_centered_string_to_stream(FILE *stream, const char *s, unsigned int width)
{
const size_t len = strlen(s);
/* If the length of the string is greater than the width
* just print the original string. */
if (len >= width)
return fprintf(stream, "%s\n", s);
/* Calculate the padding. */
const unsigned int p = (len >= width) ? 0 : (width - len) / 2;
return fprintf(stream, "%*.*s%s%*.*s", p, p, " ", s, p, p, " ");
}
int
printf_centered_string(FILE *stream, const struct printf_info *info, const void *const *args)
{
const char *s = *((const char **) (args[0]));
return print_centered_string_to_stream(stream, s, info->width);
}
int
printf_centered_string_arginfo(const struct printf_info *info, size_t n, int *argtypes, int *size)
{
if (n > 0)
argtypes[0] = PA_POINTER;
return 1;
}
int
main(void)
{
register_printf_specifier('Q', printf_centered_string, printf_centered_string_arginfo);
printf("|%40Q|\n", "Hello, World");
printf("|%80Q|\n", "Hello, World");
printf("|%25Q|\n", "Hello, World");
}
† Обратите внимание, что в документации GNU используется устаревшая функция register_printf_function.