Один из способов сделать это - сохранить значения по мере их поступления в массив и отследить наибольшее значение в каждом столбце, затем отформатировать это значение, чтобы выяснить его длину, и из этого вывести значения в указать.
Вот код, который делает это:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int cols = 3;
int prec = 13;
if (argc > 3)
{
fprintf(stderr, "Usage: %s [precision [columns]]\n", argv[0]);
exit(EXIT_FAILURE);
}
if (argc > 1)
prec = atoi(argv[1]);
if (argc > 2)
cols = atoi(argv[2]);
double max[cols];
for (int i = 0; i < cols; i++)
max[i] = 0.0;
enum { MAX_DATA = 100 };
double data[MAX_DATA];
int count = 0;
double x;
while (scanf("%lf", &x) == 1 && count < MAX_DATA)
{
int colnum = count % cols;
if (x > max[colnum])
max[colnum] = x;
data[count++] = x;
}
int width[cols];
const char *pad[cols];
for (int i = 0; i < cols; i++)
{
pad[i] = (i == 0) ? "" : " ";
width[i] = snprintf(0, 0, "%.*f", prec, max[i]);
if (width[i] < 4 + prec)
width[i] = 4 + prec;
}
for (int i = 0; i < count; i++)
{
int colnum = i % cols;
printf("%s%*.*f", pad[colnum], width[colnum], prec, data[i]);
if (colnum == cols - 1)
putchar('\n');
}
if (count % cols != 0)
putchar('\n');
return 0;
}
Обратите внимание, что код осторожен, чтобы отклонить слишком много аргументов, а не для доступа к аргументам, которые не существуют. Я также удалил подсказку; я никак не могу набирать цифры от руки, а когда ввод поступает из файла, приглашение просто создает неудобства.
Кроме того, стандарт * документирует использование snprintf()
с нулевой длиной (и, возможно, нулевым указателем) как способ получения количества места, необходимого для форматирования строки.
Принимая во внимание некоторые примеры данных, подобные этим (генерируемые случайным образом, но затем сфальсифицированные так, чтобы в каждом столбце было значение 10 КБ, а также значение «одна цифра перед десятичной точкой» в каждом столбце - в макете по умолчанию с 3 столбцами) :
2730.8075416749843 9153.7050562644145 8264.2778874481955
5393.9722906483921 9659.6077493184748 59.6077493184748
4973.9718947965630 3.7623787002290 5975.6392547304667 682.2153319663826
6236.5964619743863 7786.2954141327737 3.7623787002290 6735.6044984396849
1069.6226524395413 8709.7209141371932 3854.7386329491574 3.7623787002290
4960.9318291197014 40.3314639772034 9017.1314461534275
1717.9459363110184 8682.9285936347133 10000 6671.2353105858210
4119.1373095038844 70.3291668437700 4528.3226201367906
1926.8741591097082 2101.4643722293158 760.9213269470772 10000
7366.6932284462664 1287.1299466478447 3418.7415326626078
3144.9791945834349 2385.3575762876035 3779.9164071168789
9743.9571880258318 10000 7432.8398636749780 3011.9532204395937
5883.0779787486517
Вывод по умолчанию выглядит следующим образом:
2730.8075416749843 9153.7050562644145 8264.2778874481955
5393.9722906483921 9659.6077493184748 59.6077493184748
4973.9718947965630 3.7623787002290 5975.6392547304667
682.2153319663826 6236.5964619743863 7786.2954141327737
3.7623787002290 6735.6044984396849 1069.6226524395413
8709.7209141371932 3854.7386329491574 3.7623787002290
4960.9318291197014 40.3314639772034 9017.1314461534275
1717.9459363110184 8682.9285936347133 10000.0000000000000
6671.2353105858210 4119.1373095038844 70.3291668437700
4528.3226201367906 1926.8741591097082 2101.4643722293158
760.9213269470772 10000.0000000000000 7366.6932284462664
1287.1299466478447 3418.7415326626078 3144.9791945834349
2385.3575762876035 3779.9164071168789 9743.9571880258318
10000.0000000000000 7432.8398636749780 3011.9532204395937
5883.0779787486517
Или с 6 знаками после запятой и 6 столбцами это выглядит так:
$ ./fmt53 6 6 < data
2730.807542 9153.705056 8264.277887 5393.972291 9659.607749 59.607749
4973.971895 3.762379 5975.639255 682.215332 6236.596462 7786.295414
3.762379 6735.604498 1069.622652 8709.720914 3854.738633 3.762379
4960.931829 40.331464 9017.131446 1717.945936 8682.928594 10000.000000
6671.235311 4119.137310 70.329167 4528.322620 1926.874159 2101.464372
760.921327 10000.000000 7366.693228 1287.129947 3418.741533 3144.979195
2385.357576 3779.916407 9743.957188 10000.000000 7432.839864 3011.953220
5883.077979
$
Или с 5 знаками после запятой и 7 столбцами:
$ ./fmt53 5 7 < data
2730.80754 9153.70506 8264.27789 5393.97229 9659.60775 59.60775 4973.97189
3.76238 5975.63925 682.21533 6236.59646 7786.29541 3.76238 6735.60450
1069.62265 8709.72091 3854.73863 3.76238 4960.93183 40.33146 9017.13145
1717.94594 8682.92859 10000.00000 6671.23531 4119.13731 70.32917 4528.32262
1926.87416 2101.46437 760.92133 10000.00000 7366.69323 1287.12995 3418.74153
3144.97919 2385.35758 3779.91641 9743.95719 10000.00000 7432.83986 3011.95322
5883.07798
$