Вывод матрицы в си

Есть следующая функция, выводящая матрицу:

void PrintMatrix(int** array, int rowsNumber, int columnsNumber)
{
     for (int i = 0;
          i < rowsNumber;
          ++i)
     {
         for (int j = 0;
              j < columnsNumber;
              j++)
         {
              printf("%d  ", array[i][j]);
         }
     printf("\n");
}

Что нужно изменить в строке с "%d ", чтобы элементы выводились ровно друг под другом в виде матрицы, ибо в текущем варианте элементы выводятся криво. И также желательно обойтись без магических чисел.


Ответы (2 шт):

Автор решения: Qwertiy

Все колонки одинаковой ширины, хвостовых пробелов нет: tio.run

#include <stdio.h>

int digits(int x)
{
  int res = x < 0;
  do ++res; while (x /= 10);
  return res;
}

void print(int **a, unsigned n, unsigned m)
{
  int min = **a, max = **a;

  for (unsigned q=0; q<n; ++q)
    for (unsigned w=0; w<m; ++w)
    {
      int cur = a[q][w];
      if (cur < min) min =  cur;
      if (cur > max) max =  cur;
    }

  int dmin = min < 0 ? digits(min) : 0;
  int dmax = digits(max);
  int width = dmin > dmax ? dmin : dmax;
  
  for (unsigned q=0; q<n; ++q)
  {
    for (unsigned w=0; w<m; ++w)
      printf("%*d", width + (w ? 3 : 0), a[q][w]);

    puts("");
  }
}

int main()
{
  int a0[] = { 1, 2, 2000, 400, 125 };
  int a1[] = { -7, 4, 1500, 99, 0 };
  int *a[] = { a0, a1 };

  print(a, 2, 5);
}
   1      2   2000    400    125
  -7      4   1500     99      0
→ Ссылка
Автор решения: Stanislav Volodarskiy

Функция MaxWidth вычисляет максимальную ширину элемента матрицы на печати. Функция PrintMatrix использует нотацию %*d которая читает ширину поля из переменной:

#include <stdio.h>
#include <string.h>

int MaxWidth(int** array, int rowsNumber, int columnsNumber) {
    int maxWidth = 0;
    char buffer[64];
    for (int i = 0; i < rowsNumber; ++i) {
        for (int j = 0; j < columnsNumber; ++j) {
            sprintf(buffer, "%d", array[i][j]);
            int w = strlen(buffer);
            if (w > maxWidth) {
                maxWidth = w;
            }
        }
    }
    return maxWidth;
}

void PrintMatrix(int** array, int rowsNumber, int columnsNumber)
{
    int w = MaxWidth(array, rowsNumber, columnsNumber);
    for (int i = 0; i < rowsNumber; ++i) {
        for (int j = 0; j < columnsNumber; ++j) {
            printf("%*d%c", w, array[i][j], (j == columnsNumber - 1) ? '\n' : ' ');
        }
    }
}

int main() {
    int row1[] = { -1, 2 };
    int row2[] = { 3, 314 };
    int *array[] = { row1, row2 };
    PrintMatrix(array, 2, 2);
}
$ gcc -std=c11 -pedantic -Wall -Wextra -Werror -O temp.c && ./a.out
 -1   2
  3 314
→ Ссылка