printf
has two seldom-used features that allow this to be done simply and directly.
The first feature is the return value from printf
. Yes, printf
actually returns something, and it's the number of characters that were printed. Consider the following two lines of code:
int width = printf("Process No.(Size) ");
int used = printf("%d(%d)", procNum[i], procSize[i]);
The first line prints the column header, and sets variable width
to the number of characters in that header. The second line prints the process information, and sets variable used
to the number of characters needed to print the two numbers, and the parentheses. So the number of space characters required between the end of the process information, and the beginning of the block information, is simply width - used
.
The second feature is the variable field width specifier. From the man page: "A field width or precision, or both, may be indicated by an asterisk '*'
[...] In this case, an int
argument supplies the field width or precision." Consider the following line of code:
printf("%*s", width - used, "");
The code is using the "%s"
conversion specifier to print a string, but the string ""
is empty, so normally nothing would be printed. But we've used an asterisk as the field width. So the argument before the string (width - used
) supplies the field width. The string will be padded with spaces to fill that width.
Note that if width - used
is less than 1, the code should set the field width to 1, so that at least one space is inserted between the process information, and the block information.
Putting it all together, the code looks like this:
#include <stdio.h>
#define max(a,b) ((a) > (b) ? (a) : (b))
int main(void)
{
int procNum[] = { 1, 2, 3 };
int procSize[] = { 200, 3, 1000 };
int blockNum[] = { 3, 1, 4 };
int blockSize[] = { 300, 50, 1200};
int width = printf("Process No.(Size) "); // print first column header, and save the width
printf("Block No.(Size)\n");
for (int i = 0; i < 3; i++)
{
int used = printf("%d(%d)", procNum[i], procSize[i]); // print process information, and save the number of characters used
printf("%*s%d(%d)\n", max(width - used, 1), "", blockNum[i], blockSize[i]); // print spaces followed by the block information
}
}