While compiling the following code:
#include <stdio.h>
int main() {
printf("99% Invisible");
return 0;
}
in gcc 7.5.0 I get the following warnings:
test.c: In function ‘main’:
test.c:4:16: warning: ' ' flag used with ‘%n’ gnu_printf format [-Wformat=]
printf("99% Invisible");
^
test.c:4:16: warning: 'I' flag used with ‘%n’ gnu_printf format [-Wformat=]
test.c:4:16: warning: format ‘%n’ expects a matching ‘int *’ argument [-Wformat=]
printf("99% Invisible");
~~~^
What is going on here? I don't see mention of a " " flag or an "I" flag anywhere in documentation. The code outputs 99visible, essentially ignoring the space and I in the format string and following the %n format.
edit: People seem to be misunderstanding the question. I know how to printf a literal %, and what %n do. I am just curious what is happening here.
(also, for those who know the context: I know the system in question didn't use C, I am just curious as to what printf is doing here).
The I flag is a GNU extension to printf. From the man page:
glibc 2.2 adds one further flag character.
I
For decimal integer conversion (i, d, u) the output uses the
locale's alternative output digits, if any. For example, since glibc
2.2.3 this will give Arabic-Indic digits in the Persian ("fa_IR") locale.
So when the compiler checks the format string, it sees % In as a format specifier, i.e. the space and I flags applied to the n conversion specifier. Since neither flag is applicable to the n conversion specifier, the compiler emits a warning for each.
To print the literal %, you must write %%.
https://en.cppreference.com/w/c/io/fprintf
I flag is not in the C standard.
It appears that with your compiler when a % character is encountered in a printf format string, it scans forward to find a valid format specifier, then interprets everything in-between as a modifier. If those are not valid modifiers, an error is flagged.
As others have pointed out, replace "99% Invisible" with "99%% Invisible" to fix the problem.
Related
What should be the output of a single percent sign?
#include <stdio.h>
void main()
{
printf("%");
}
"Unknown format code" is not like "Unknown escape sequence".
What you're doing is undefined behavior.
Section 7.21.6.1p9 of the C standard regarding format specifiers for fprintf (and by extension printf) states:
If a conversion specification is invalid, the behavior is undefined. If any argument is
not the correct type for the corresponding conversion specification, the behavior is
undefined.
Also, gcc will generate a warning with -Wall if you do this:
warning: spurious trailing ‘%’ in format [-Wformat=]
The correct way to print a % character is with the format specifier %%.
printf("%%");
% is used to signal that you want to print a variable e.g.
int i = 10;
printf("%d", i); //prints 10
In order to just print the '%' sign you must escape it as
printf("%%");
This program doesn't work and I don't know why.
#include <stdio.h>
int main()
{
printf("%а", 20.0);
}
I am compiling in C99. Expected output is 0x1.4p+4
The а is CYRILLIC SMALL LETTER A (U+0430), but you have to use LATIN SMALL LETTER A (U+0061): a.
If you're using a compiler that is able to check format strings like Clang or GCC, then compile with (at least) -Wall which includes -Wformat (GCC Warning documentation)
5 : warning: unknown conversion type character 0xffffffd0 in format [-Wformat]
5 : warning: too many arguments for format [-Wformat-extra-args]
Its really wired. When I copypaste your code it turns into printf("%?", 20.0);
You should check your character encoding.
I got
program.cpp: In function ‘int view_next(FILE*)’:
program.cpp:118: warning: unknown conversion type character ‘)’ in format
when I try to compile (gcc -o program program.cpp) but I don't know how to fix it. Can someone please give me a hand?
printf("\033[7m--More--(%.0f%)\033[m", float(file_size) /
float(buffIn.st_size) * 100);
this:
printf("\033[7m--More--(%.0f%)\033[m", float(file_size) /
should be:
printf("\033[7m--More--(%.0f%%)\033[m", float(file_size) /
read (or google) man 3 printf
What is happening here, is that the % character is used in functions of the printf family to signal that a format specifier is following. To print a literal % character, you can escape it with another % character.
printf("%%\n"); // prints a literal %
This is a minimal example that reproduces your error:
printf("%)\n"); // errors
And here is the fix to the minimal example:
printf("%%)\n"); // prints "%)"
I'm stuck fixing ancient code, and here is today's issue:
output_file_status = fprintf ( data_file, "%03d%08s%+014.2f%06.3f%",
LongValue, CharStarValue, Double1, Double2 );
Lint32 produces: Lint32 results in “malformed format string”
1) Do you all agree the format string can not end in a % sign? I don't believe a standalone % has meaning.
2) When I either remove the trailing %, or append an additional %, I still get the same warning.
This is using the Oracle Pro*C compiler (so the CharStarValue is actually a (char*)VarChar.arr ).
Yes, you are correct that % by itself at the end is an error. It should be %% to produce one literal % in the formatted output.
It might be that your linter is also complaining about the use of %03d with a long value. That should be %03ld.
Taking it piece by piece:
"%03d" expects an int. OP supplies a LongValue. With a long, specifier should be "%03ld".
"%08s" expects a pointer to char. OP supplies CharStarValue. OK. But the "0" in the specifier is undefined behavior for a %s. Recommend "%8s"
"%+014.2f" expects a double. OK. Flags '+', '0' are OK.
"%06.3f" expects a double. OK. Flags '+', '0' are OK.
"%" should have something after it else behavior is undefined. Recommend removal or "%%".
To OP's 2 points
1 A proper format should not end with a lone %, but may end with paired %%s.
A standalone % introduces "If a conversion specification is invalid, the behavior is undefined" C11 7.21.6.1 9.
2 To get rid of all warnings, try "%03ld%8s%+014.2f%06.3f".
I don't know how this C program I'm meant to compile works exactly. I'm compiling it on a MacBook so maybe that explains the unusual errors? Anyway the compiled program doesn't seem to be working correctly. When compiled, I get these:
ers.c: In function ‘evolve’:
ers.c:205: warning: unknown conversion type character 0xa in format
ers.c: In function ‘print_rule’:
ers.c:304: warning: unknown conversion type character 0xa in format
ers.c: In function ‘test_evaluate’:
ers.c:380: warning: unknown conversion type character 0xa in format
Which refer to these lines of code:
if(i%100==0)printf("best on training set at iteration %d: %g\%\n", i,100.0* population[bestinpop].acc);
printf("ACCURACY on training set %g\%\n\n", 100.0* r->acc);
printf("TEST ACCURACY %g\%\n", 100.0* r->acc);
I suspect it to be something to do with that %g type formatting.
Can anyone see what is being done wrong?
The 0xa in ASCII encoding is the Line Feed character \n, so your errors are indeed coming from the "%\n" constructs
I assume that the original developer meant "%%" and not "\%" (to display '%' characters). But I don't believe that this program ever compiled on any platform.
BTW : %g is an alternative formatting character for double (output is same as %f or %e, depending on the double value).
"%\n" is not a valid format specifier. If you need the % character to be part of the output you need to use "%%".