You can specify the column width by putting a number between the % and f so, for example:
printf("||%10f|%10f|%10f|%10f||\n", box.x, box.y, box.z, box.volume);
would print:
|| 3.100000| 2.000000| 9.500000| 58.899998||
Notice these are right aligned. If you put a minus sign in front of the column width, you can make it left aligned.
printf("||%10f|%10f|%10f|%-10f||\n", box.x, box.y, box.z, box.volume);
will print:
|| 3.100000| 2.000000| 9.500000|58.899998 ||
It's also useful to know that you can control the number of digits shown after the decimal point by specifying .<count> after the column width:
printf("||%10.2f|%10.2f|%10.2f|%10.4f||\n", box.x, box.y, box.z, box.volume);
will print
|| 3.10| 2.00| 9.50| 58.9000||
Update:
It looks like you've added more details to your question. Here's additional information that you could use.
The width and precision numbers do not have to be constants in the format string. You can replace any or all of them with an asterisk '*' and supply a variable like this:
for (int precision = 1; precision < 5; ++precision) {
int width = precision * 4;
printf("||%*.*f|%*.*f|%*.*f|%*.*f||\n",
width, precision, box.x,
width, precision, box.y,
width, precision, box.z,
width, precision, box.volume);
}
This will produce:
|| 3.1| 2.0| 9.5|58.9||
|| 3.10| 2.00| 9.50| 58.90||
|| 3.100| 2.000| 9.500| 58.900||
|| 3.1000| 2.0000| 9.5000| 58.9000||
A quick way of determining the number of digits before the decimal point is:
int digits = (int)log(values[i])/log(10) + 1;
so if you run through your data beforehand you can decide an appropriate column width.
As for digits after the decimal point, that decision is up to you; the quirks of floating point representations can lead to result an end-user might find confusing. For example in the data I used above 3.1 * 2.0 * 9.5 is printed as 58.899998 if allowed to print all digits, whereas 5.9 is probably what end-users would expect.