What does "%.*s" mean in printf?
Solution 1
You can use an asterisk (*
) to pass the width specifier/precision to printf()
, rather than hard coding it into the format string, i.e.
void f(const char *str, int str_len)
{
printf("%.*s\n", str_len, str);
}
Solution 2
More detailed here.
integer value or
*
that specifies minimum field width. The result is padded with space characters (by default), if required, on the left when right-justified, or on the right if left-justified. In the case when * is used, the width is specified by an additional argument of type int. If the value of the argument is negative, it results with the - flag specified and positive field width. (Note: This is the minimum width: The value is never truncated.)
.
followed by integer number or *, or neither that specifies precision of the conversion. In the case when * is used, the precision is specified by an additional argument of type int. If the value of this argument is negative, it is ignored. If neither a number nor * is used, the precision is taken as zero. See the table below for exact effects of precision.
So if we try both conversion specification
#include <stdio.h>
int main() {
int precision = 8;
int biggerPrecision = 16;
const char *greetings = "Hello world";
printf("|%.8s|\n", greetings);
printf("|%.*s|\n", precision , greetings);
printf("|%16s|\n", greetings);
printf("|%*s|\n", biggerPrecision , greetings);
return 0;
}
we get the output:
|Hello wo|
|Hello wo|
| Hello world|
| Hello world|
Solution 3
I don't think the code above is correct but (according to this description of printf()
) the .*
means
The width is not specified in the format string, but as an additional integer value argument preceding the argument that has to be formatted.'
So it's a string with a passable width as an argument.
Solution 4
See: http://www.cplusplus.com/reference/clibrary/cstdio/printf/
.*
The precision is not specified in the format string, but as an additional integer value argument preceding the argument that has to be formatted.
s
String of characters
Comments
-
StevenWang over 3 years
I got a code snippet in which there is a
printf("%.*s\n")
what does the
%.*s
mean?-
Andrew Marshall over 12 yearsWithout additional arguments, that is not a valid
printf
call.
-
-
Jonathan Leffler about 9 yearsI've added the URL cross-reference so you can avoid charges of plagiarism. Of course, the correct quote says "The precision is not …" rather than "The width is not…".
-
M.M almost 9 yearsIt should be noted that the
str_len
argument must have typeint
(or narrower integral type, which would be promoted toint
). It would be a bug to passlong
,size_t
, etc. -
Anton Samsonov almost 9 yearsAs @MattMcNabb pointed out, every reference to that page must highlight that “an integer value” is exactly
int
(or a subset of it) — not just any integral value like more intuitivesize_t
or its possible aliases, likestd::string::size_type
. This is even more confusing, taking into account that the referenced page mentionssize_t
as one of supported type specifiers. -
Sonic Atom over 8 yearsIt's worth mentioning that the likely purpose of this code, especially when used with
%s
, is to print a sub-string of the original string. In this use case,str
would point to somewhere inside the original string (possibly at the beginning), andstr_len
will specify the length of the sub-string that should be printed. -
Admin over 5 yearsBy specifying a length, we can get around printing (or sprintf) 'ing a string which has no null terminator, for example a string which is input from any stream or file based source. Which is far more often the use case I have encountered, than merely print prettines.
-
powersource97 over 2 yearsFrom the docs, the major difference between '%.*s' and '%*s' seems to be that the former ignore negative values for precision while the later takes in into consideration to apply the appropriate justification.
-
kenn over 2 yearsYou could also add
printf("|%.*s|\n", biggerPrecision , greetings);