I might solve it like this
/* ... mystery content removed ... */
int main(int argc, char **argv)
{
for (int i = 1; i < argc; i++)
printf("Left: " PAD_STAR_FMT "\n", PAD_STAR_ARG(argv[i], 20));
for (int i = 1; i < argc; i++)
printf("Rite: " PADR_STAR_FMT "\n", PADR_STAR_ARG(argv[i], 20));
return 0;
}
Run:
$ ./pad The quick brown fox "" "supercalifragilisticexpeali"
Left: *****************The
Left: ***************quick
Left: ***************brown
Left: *****************fox
Left: ********************
Left: supercalifragilistic
Rite: The*****************
Rite: quick***************
Rite: brown***************
Rite: fox*****************
Rite: ********************
Rite: supercalifragilistic
The PAD_STAR_FMT and PADR_STAR_FMT macros expands to a string literal which provides the conversion specifier for the star-padded print job.
The PAD_STAR_ARG and PADR_STAR_ARG macros expand to the argument to this conversion specifier.
As you can see, we encode the field width of 20 into the argument space rather than the format string because we need to be able to do some calculations with it, not possible in the format string language.
Under the hood, two conversion specifiers are used, and the ARG macros generate several arguments for them (unfortunately, with multiple evaluations of their own arguments).
The nice thing about this approach is that we can retrofit it into some existing code that already uses printf without otherwise disturbing that code. If the code makes a single printf call, we can keep it that way.
I recommend cleaning up the code and using better, perhaps shorter names. My if statements could be ternary operators, too.
The complete program follows:
#include <stdio.h>
#include <string.h>
#include <assert.h>
static char stars[] = {
"**************************************************"
"**************************************************"
"**************************************************"
"**************************************************"
"**************************************************"
"**************************************************"
"**************************************************"
"**************************************************"
"**************************************************"
"**************************************************"
};
#define PAD_STAR_FMT "%.*s%.*s"
#define PAD_STAR_ARG(S, N) pad_nstars(S, N), stars, pad_nchars(S, N), (S)
#define PADR_STAR_FMT "%.*s%.*s"
#define PADR_STAR_ARG(S, N) pad_nchars(S, N), (S), pad_nstars(S, N), stars
static int pad_nstars(const char *s, size_t width)
{
assert (width < sizeof stars);
size_t len = strlen(s);
if (len > width)
return 0;
return (int) (width - len);
}
static int pad_nchars(const char *s, size_t width)
{
size_t len = strlen(s);
if (len > width)
return width;
return len;
}
int main(int argc, char **argv)
{
for (int i = 1; i < argc; i++) {
printf("Left: " PAD_STAR_FMT "\n", PAD_STAR_ARG(argv[i], 20));
}
for (int i = 1; i < argc; i++) {
printf("Rite: " PADR_STAR_FMT "\n", PADR_STAR_ARG(argv[i], 20));
}
return 0;
}