Substrings With Printf
You can specify a precision with printf’s %s
conversion to limit how
many characters are printed:
const char *greeting = "Hello, World!\n";
printf("%.5s\n", greeting); // prints "Hello\n"
But what if you don’t know until runtime how many characters you need?
From man 3 printf
:
Instead of a decimal digit string one may write “*” or “*m$” (for some decimal integer m) to specify that the precision is given in the next argument, or in the m-th argument, respectively, which must be of type int.
This is awesome for printing substrings. Example:
struct token {
const char *start; // start of the token inside a source string
int length; // number of characters in the token
};
void print_token(FILE *out, struct token token)
{
fprintf(out, "<\"%.*s\">", token.length, token.start);
}
The “*m$” syntax comes from a POSIX extension to the C standard that lets you specify which argument to use for each conversion. This is helpful if you want to use the same argument more than once:
void print_token(FILE *out, struct token token)
{
fprintf(out, "<\"%1$.*2$s\" (%2$d characters)>",
token.start, token.length);
}
Note that you can’t mix numbered and unnumbered conversions in the same
format string, so if you use *m$
for the precision, you also need to
use %m$
for the conversion itself.