I know %%
is used to escape actual %
signs in a string, so %%%ds
will end up with %10s
in the following format string, but I don't know why I need %%5s
in this string?
After all, there are only two additional arguments (BUFFSIZE / 10).
#define BUFFSIZE 100
char buf[100]={0}
sprintf(buf, "%%5s %%%ds %%%ds", BUFFSIZE / 10, BUFFSIZE / 10);
After running the code above, the buf will contain the string,
%10s %10s
You can do this by using %% in the printf statement. For example, you can write printf(“10%%”) to have the output appear as 10% on the screen.
The %s operator is put where the string is to be specified. The number of values you want to append to a string should be equivalent to the number specified in parentheses after the % operator at the end of the string value.
The %s signifies that you want to add string value into the string, it is also used to format numbers in a string. After writing the above code (what does %s mean in python), Ones you will print ” string “ then the output will appear as a “ Variable as string = 20 ”.
Python uses C-style string formatting to create new, formatted strings. The "%" operator is used to format a set of variables enclosed in a "tuple" (a fixed size list), together with a format string, which contains normal text together with "argument specifiers", special symbols like "%s" and "%d".
The purpose is to get a format string to use it in another function that needs a format string like sscanf()
.
With your code you get: %5s %10s %10s
written to your buf
, see online, which means it will accept three strings with a length identifier.
%%5s --> %5s
%%%ds with 10 --> %10s (read it that way: {%%}{%d}{s})
That buffer %5s %10s %10s
could now be used in a sscanf()
call like shown here.
But there is a best practice to prevent a buffer overflow caused by sscanf()
which is also described by Kernighan and Pike in their book The Practice of Programming, see here on SO.
The reason why you maybe can't use %*s
may be, see here on SO:
For
printf
, the * allows you to specify minimum field width through an extra parameter, i.e.printf("%*d", 4, 100);
specifies a field width of 4.For
scanf
, the * indicates that the field is to be read but ignored, so that i.e.scanf("%*d %d", &i)
for the input "12 34" will ignore 12 and read 34 into the integer i.
%
in itself is a valid conversion specifier. The prescribed syntax is, as mentioned in C11
, chapter §7.21.6.1/P2, (emphasis mine)
Each conversion specification is introduced by the character
%
. After the%
, the following appear in sequence:
Zero or more flags [...]
An optional minimum field width.
An optional precision [...]
An optional length modifier [...]
A conversion specifier character that specifies the type of conversion to be applied.
Then, from P8, for conversion specifiers
The conversion specifiers and their meanings are:
......
%
A
%
character is written. No argument is converted. The complete conversion specification shall be%%
.
So, based on greedy approach, compiler will group a syntax like
.... %%%ds, BUFFSIZE / 10 ....
as
{%%}{%d}{s}
^^--------------------------Replaced as %
^^----------------------Actual conversion specification happens, argument is used
^^------------------just part of final output
which finally produces
%Xs //where X is the value of (BUFFSIZE / 10)
which is a valid format string (%
, minimum field width, conversion specifier, all in order), again, to be used later.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With