Как отформатировать строку и сделать ровную таблицу
Есть клиент, который запрашивает информацию у сервера. Получает данные с помощью recv()
Например:
char buffer[1024];
if (recv(sock, buffer, sizeof(buffer), 0) == -1)
error_wrap("recv() returned negative value");
В буфере лежат данные о пользователях, которые выглядят так:
"Anna 408 32 02:23\nUser1 371 21 02:37\nEgor 363 37 02:52\n\000\"
Хотелось бы сделать таблицу вывода с этими данными, например:
Nickname WPM Errors Time
Anna 408 32 02:23
User1 371 21 02:37
Egor 363 37 02:52
Мое решение довольно простое:
for (int i = 0; buf[i] != '\0'; i++) {
printf("%c", buf[i]);
if (buf[i] == ' ')
printf("%10c", ' ');
}
Только в выводе я получаю:
Anna 408 32 02:23
User1 371 21 02:37
Egor 363 37 02:52
Как можно подровнять колонки? Заранее благодарен
Ответы (2 шт):
Ну, как вариант, создаем некую функцию, цель которой расставить нужное количество пробелов в каждой строке.
- Вы определяетесь с минимальным количеством пробелов между столбцами (допустим 6).
- Смотрите, какая строка в каком столбце длиннее всего. Ставите туда 6 пробелов.
- Проходитесь по этому столбцу по всем строкам и из длинны самой длинной строки столбца вычитаете длину текущей строки текущего столбца.
и т.д. Например:
"Anna 408 32 02:23\nUser1 371 21 02:37\nEgor 363 37 02:52\n\000\"
Для удобства представим как
Anna 408 32 02:23
User1 371 21 02:37
Egor 363 37 02:52
Берем первый столбец. Самая длинная строка имеет 5 символов (User1). Нам нужно расстояние между столбцами 6 пробелов (минимум). Ставим после User1 6 пробелов. Anna и Egor - 4 символа, а User1 имеет 5 символов, значит 5 - 4 = 1. Нам нужно 6 пробелов в каждой строке минимум, а значит 1 + 6 = 7. Ставим 7 пробелов после Anna и Egor.
Таким образом до второго столбца в каждой строке будет ровно 11 символов.
Anna 408 32 02:23
User1 371 21 02:37
Egor 363 37 02:52
После, анализируйте так же каждый столбец. Может это и не лучший способ, но он довольно прост.
В самом примитивном варианте можно сделать как-то так:
for (char *s=buf; s;) {
bool add_endl = false;
char *next = strpbrk(s, " \n");
if(next) {
char sep = *next ;
*next=0;
printf("%-15s%c", s, sep);
}
s = next+1;
}
Основные идеи:
- Ищем конец текущего поля и заменяем его нулём.
- Выводим всю строку сразу с помощью
printf, задав размер поля (15) и, по желанию, выравнивание по левому краю (-).
Обычные расширения:
Разная ширина для каждого столбца — делается или просто добавлением счётчика в цикл, или предварительным парсингом всей строки, а потом выводом за один
printf()Автоматический подсчёт ширины столбцов — придётся делать в 2 прохода: сначала найти максимальную ширину столбца, а затем выводить. Стоит также освежить память, как работает динамическое задание ширины (
"%*s") вprintf().Вывод без модификации исходного буфера — тоже самое, что и выше но с использованием спецификатора
"%.s", примерно так:printf("%-15.*s%c", next-s, s, sep);Учёт ширины терминала — требуются системно-зависимые функции