Say I have a printf with many parameters:
printf("%d %d %d %d", A, B, C, D);
For some reason I would like one parameter to no longer be printed, but still be listed in the parameter list (for instance for visual reason, or maybe it's a function call with a necessary side effect, etc).
Can I replace %d with a conversion letter with no output ? I don't recall such a conversion letter. Or maybe playing with the flags...?
[Edit] I just noticed that scanf has something similar (but the reverse): an assignment suppression flag '*'. for instance sscanf("123 345 678", "%i %*i %i", &a, &b) will lead to a=123 b=678
If you for some reason must change these on the fly, then keep things simple:
printf("%d ", A);
printf("%d ", B);
if(c)
printf("%d ", C);
printf("%d ", D);
You can suppress Strings (char*) arguments by specifying zero-width.
However, I know of no way to suppress numeric (int and float) values.
int main(void) {
int a=1;
char* b="hello"; // Gets Suppressed
int c=3;
printf("%d %.0s %d\n", a, b, c); // .0 means "zero-width"
return 0;
}
First of all, I agree with Radosław Cybulski's comment: Relying on side-effects is a dangerous thing. So please don't do that.
As for suppressing the printing of a parameter I think there is no built-in placeholder for that and it would probably be better to just comment out the whole printf statement and add the version without the suppressed parameter below it.
With that said there are two(not very elegant) solutions I could come up with that does something similar to what you'd like to achieve:
Method1
You could create a macro like this:
#define SUPPRESS_PRINT(x) "\0"/*x*/
This will replace the parameter with a null terminator character.
Then you can use it in your printf statement like this:
printf("%d %d %s %d", A, B, SUPPRESS_PRINT(C), D);
Notice that the placeholder for C (i.e. the suppressed parameter) had to be changed to %s that is a null terminated string in order for this "trick" to yield the desired result.
Correction:
I've enhanced the above solution thanks to jhx's awesome suggestion in the comments. Using sequential evaluation possible side-effects won't be omitted. The revised macro would look like this:
#define SUPPRESS_PRINTF_ARG(x) ((x), "")
Usage would stay the same as described above.
Method2
There is yet another, possibly simpler, solution. It is a POSIX feature not a C99 one but it would work in most scenarios I assume. It is to use a parameter field in each format placeholder. Something like this:
printf("%1$d %2$d %3$d %4$d", A, B, C, D);
Then if you'd want to omit let's say parameter C from being printed you could just delete %3$d from the format string. Thus getting this:
printf("%1$d %2$d %4$d", A, B, C, D);
This might be the simplest way to go about it.
Working principle: The parameter field ties the format placeholder to a given parameter using its ordinal number. Thus even if you remove one the rest will still print correctly.
Note: As far as my testing goes this method does not omit side-effects!
Related
Most of the time I use C++ to deal with URI Online problems, but this time I need to use C.
I have solved the computational part, but URI keeps giving me the classical “Presentation error problem”.
I know I have to break the line at the end, but neither \n or \r\n nor anything else seems to fix this problem.
Here's my code:
int main () {
double R,PI,a;
PI = 3.14159;
scanf("%lf", &R);
a = PI * (pow(R,2));
printf ("A=%0.4f", a, "\n");
return 0;
}
You misunderstood how printf works. It does not concatenate all the stuff you throw into it like you're used to from std::cout << … << …; but instead mostly prints the first argument, the format string. The latter arguments only come into play when the format string requests them, as you do with the %0.4f for the second argument. However, the third is unused. You could fix it like this:
printf("A=%0.4f%s", a, "\n");
Or, more idiomatically, like this:
printf("A=%0.4f\n", a);
By the way, at least my gcc warns me:
main.c: In function ‘main’:
main.c:…: warning: too many arguments for format [-Wformat-extra-args]
printf ("A=%0.4f", a, "\n");
#include<stdio.h>
#define PRINT(A,B) printf("Value of expression %s is %*",#A,#B,(A))
int main(void){
PRINT(1+3+1,%d);
return 0;
}
How to write a macro which gets two arguments: expression and format specifier then printing expression and value of it in given format?
%d is a format string, so it needs to be in double quotes, like any other string literal. Also, use meaningful names for identifiers.
#define PRINT(expr, fmt) printf("Value of expression %s is " fmt "\n", #expr, expr)
PRINT(1+3+1, "%d");
You can get away with the preprocessor's stringification operator to turn something like %d into "%d", but it's fragile (it's very sensitive to whitespace), risk-prone (code analysis tools that don't run a preprocessor may think that the code is using the variable d or choke on a syntax error on % with no left-hand side), and most importantly, it's misleading for human readers.
As a rule of thumb, you should only use unhygienic macros (macros that depart from the syntax of the language) if you have a very good reason. Typesetting an expression for debugging purposes (#expr) is a good reason. Writing programs that are two characters shorter is a good reason only if you're entering an obfuscated programming contest.
You could try something like this;
#define PRINT(A,B) printf("Value of expression %s is "#B"\n",#A,(A))
The result of this code down below should be 30, however when compiled and run this is giving me the following result
the result of 2358968 and 0 is 4200271, a , b , result
I
don't understand when I have no variables of that value how could the result be like that?
#include<stdio.h>
#include<conio.h>
void add( int , int );
int main(){
add(10,20);
getch();
return 0 ;
}
void add(int a, int b){
int result = a + b;
printf("the result of the %d and %d is %d, a, b, result");
}
In your code,
printf("the result of the %d and %d is %d, a, b, result");
should be
printf("the result of the %d and %d is %d\n", a, b, result);
^
|
//format string ends here
// arguments for format specifiers are meant to be
// supplied as different arguments to `printf()`, not as a part of <format> string itself
From the man page of printf()
int printf(const char *format, ...);
and
The functions in the printf() family produce output according to a format ....
So basically your code should be
printf("<format>", var1, var2,....);
The supplied variables are not part of the format.
The problem in your code were missing variables (arguments) for supplied format specifiers. As per the C11 standard , chapter 7.21.6.1, paragraph 2
[...] If there are insufficient arguments for the format, the behavior is
undefined. [...]
So, your code produces undefined behaviour printning out some junk value.
Moral of the Story : If you had enabled compiler warnings, you compiler should warn you about missing (mismatch) agruments in printf(). So, always enable warnings.
You have closed the " at the end of the line. and in the printf function you have specified the %d So the %d will not have the variable to point and fetch the value.
You will get the warning message that %d expects a matching int
It will have the garbage value in that position, So it is printing some value.
Sourav Ghosh answered to most of your questions; he rightly suggested to enable all warnings when compiling. If your compiler is (notably on Linux) some recent GCC or Clang/LLVM pass -Wall -Wextra -g to the gcc or clang command (to get nearly all warnings, some extra ones, and debug information). Others compiler options (-fsanitize=address etc etc...) and other tools (the gdb debugger, the valgrind tool, strace, ...) might be useful too!
I dont understand when I have no variables of that value how could the
result be like that?
Because you have encountered undefined behavior. Read much more about it (in particular Lattner's blog on What Every C Programmer should know about Undefined Behavior), and work hard to always avoid it in all cases. Be aware that with UB, your (or any other) program might seems to work while in fact it has some undefined behavior.
The particular garbage (or apparently random) values that are printed : might not be reproducible, and can be explained only by diving into every implementation details, including looking into the machine code generated by your particular compiler and inspecting some machine state (register values); concretely the printf implementation on your system is probably using some stdarg(3) things and fetching some values from uninitialized memory or register which happens to have some previous "garbage" value (at the machine level).
See also this answer (and many others) about undefined behavior. Work hard to always avoid it.
Remember that when coding (even in C) you are ultimately coding for some virtual or abstract machine which is not the real computer. Even if writing all the software levels from the operating system kernel included - that would take you many dozens of years at least -, you are coding for some specified abstraction and you have to ignore some misbehavior of your computer (e.g. if it breaks, get some cosmic rays, etc etc...) outside of these abstractions. The C99 or C11 programming language standard specification (a technical document of several hundred pages in English), with the POSIX 2008 operating system specification, are useful abstractions to code software for.
printf statement is the reason for undesired output,
printf("the result of the %d and %d is %d, a, b, result");
There is no arguments specified for format specifier, the position of " has to be changed.
the statement should be like this
printf("the result of the %d and %d is %d", a, b, result);
In your printf statement it was taking garbage value since no arguments were specified there for %d.
printf("the result of the %d and %d is %d, a, b, result");
it has to be
printf("the result of the %d and %d is %d", a, b, result);
it will read and assign the %d value from left to write.
printf returns number of characters
i am trying to print value of an array in C-language.I am using 3 format specifier for only one value of array , my problem is that i don't understand that how other two values are coming in my output .
here is my code:
int arr[6] = {3,4,42,2,77,8};
printf("%d %d %d ",arr[2]);
output :
42 3 4
According to the C Standard
If there are insufficient arguments for the format, the behavior is
undefined.
In your call of printf
printf("%d %d %d ",arr[2]);
the arguments are exhausted after the first format specjfjer. So the function call has undefined behaviour and the output can contain any garbage.
You shall write
printf( "%d ", arr[2] );
or for example
printf( "%d %d %d ", arr[2], arr[3], arr[4] );
When printf() sees three format specifiers, it looks at specific locations, either in stack memory or in CPU registers, depending on the conventions of the compiler, for three arguments.
You provided one, but some data that you have no control over exists in the other two locations, and that's what gets printed.
The other two values are garbage and don't have any meaning. The function printf requires as many arguments as there are format specifiers, so in your case three. Since you only provided one argument (arr[2]), the other two specifier 'don't know' what to print - thus gargabe will come out. Make sure to provide the required number of arguments.
If you want to print the array number by number, you will have to use a for loop.
The signature of printf is.
int printf(char*, ...);
So, you can have a variable number of arguments, then.
printf("%d %d %d ",arr[2]);
Is a valid call of the function printf.
However, because you provided no values yourself, then you will get whatever... that in your special case it seems that it printed arr[0] and arr[1].
What is the use of the %n format specifier in C? Could anyone explain with an example?
Most of these answers explain what %n does (which is to print nothing and to write the number of characters printed thus far to an int variable), but so far no one has really given an example of what use it has. Here is one:
int n;
printf("%s: %nFoo\n", "hello", &n);
printf("%*sBar\n", n, "");
will print:
hello: Foo
Bar
with Foo and Bar aligned. (It's trivial to do that without using %n for this particular example, and in general one always could break up that first printf call:
int n = printf("%s: ", "hello");
printf("Foo\n");
printf("%*sBar\n", n, "");
Whether the slightly added convenience is worth using something esoteric like %n (and possibly introducing errors) is open to debate.)
Nothing printed. The argument must be a pointer to a signed int, where the number of characters written so far is stored.
#include <stdio.h>
int main()
{
int val;
printf("blah %n blah\n", &val);
printf("val = %d\n", val);
return 0;
}
The previous code prints:
blah blah
val = 5
I haven't really seen many practical real world uses of the %n specifier, but I remember that it was used in oldschool printf vulnerabilities with a format string attack quite a while back.
Something that went like this
void authorizeUser( char * username, char * password){
...code here setting authorized to false...
printf(username);
if ( authorized ) {
giveControl(username);
}
}
where a malicious user could take advantage of the username parameter getting passed into printf as the format string and use a combination of %d, %c or w/e to go through the call stack and then modify the variable authorized to a true value.
Yeah it's an esoteric use, but always useful to know when writing a daemon to avoid security holes? :D
From here we see that it stores the number of characters printed so far.
n The argument shall be a pointer to an integer into which is written the number of bytes written to the output so far by this call to one of the fprintf() functions. No argument is converted.
An example usage would be:
int n_chars = 0;
printf("Hello, World%n", &n_chars);
n_chars would then have a value of 12.
So far all the answers are about that %n does, but not why anyone would want it in the first place. I find it's somewhat useful with sprintf/snprintf, when you might need to later break up or modify the resulting string, since the value stored is an array index into the resulting string. This application is a lot more useful, however, with sscanf, especially since functions in the scanf family don't return the number of chars processed but the number of fields.
Another really hackish use is getting a pseudo-log10 for free at the same time while printing a number as part of another operation.
The argument associated with the %n will be treated as an int* and is filled with the number of total characters printed at that point in the printf.
The other day I found myself in a situation where %n would nicely solve my problem. Unlike my earlier answer, in this case, I cannot devise a good alternative.
I have a GUI control that displays some specified text. This control can display part of that text in bold (or in italics, or underlined, etc.), and I can specify which part by specifying starting and ending character indices.
In my case, I am generating the text to the control with snprintf, and I'd like one of the substitutions to be made bold. Finding the starting and ending indices to this substitution is non-trivial because:
The string contains multiple substitutions, and one of the substitutions is arbitrary, user-specified text. This means that doing a textual search for the substitution I care about is potentially ambiguous.
The format string might be localized, and it might use the $ POSIX extension for positional format specifiers. Therefore searching the original format string for the format specifiers themselves is non-trivial.
The localization aspect also means that I cannot easily break up the format string into multiple calls to snprintf.
Therefore the most straightforward way to find the indices around a particular substitution would be to do:
char buf[256];
int start;
int end;
snprintf(buf, sizeof buf,
"blah blah %s %f yada yada %n%s%n yakety yak",
someUserSpecifiedString,
someFloat,
&start, boldString, &end);
control->set_text(buf);
control->set_bold(start, end);
It doesn't print anything. It is used to figure out how many characters got printed before %n appeared in the format string, and output that to the provided int:
#include <stdio.h>
int main(int argc, char* argv[])
{
int resultOfNSpecifier = 0;
_set_printf_count_output(1); /* Required in visual studio */
printf("Some format string%n\n", &resultOfNSpecifier);
printf("Count of chars before the %%n: %d\n", resultOfNSpecifier);
return 0;
}
(Documentation for _set_printf_count_output)
It will store value of number of characters printed so far in that printf() function.
Example:
int a;
printf("Hello World %n \n", &a);
printf("Characters printed so far = %d",a);
The output of this program will be
Hello World
Characters printed so far = 12
Those who want to use %n Format Specifier may want to look at this:
Do Not Use the "%n" Format String Specifier
In C, use of the "%n" format specification in printf() and sprintf()
type functions can change memory values. Inappropriate
design/implementation of these formats can lead to a vulnerability
generated by changes in memory content. Many format vulnerabilities,
particularly those with specifiers other than "%n", lead to
traditional failures such as segmentation fault. The "%n" specifier
has generated more damaging vulnerabilities. The "%n" vulnerabilities
may have secondary impacts, since they can also be a significant
consumer of computing and networking resources because large
guantities of data may have to be transferred to generate the desired
pointer value for the exploit. Avoid using the "%n" format
specifier. Use other means to accomplish your purpose.
Source: link
In my opinion, %n in 1st argument of print function simply record the number of character it prints on the screen before it reach the the %n format code including white spaces and new line character.`
#include <stdio.h>
int main()
{
int i;
printf("%d %f\n%n", 100, 123.23, &i);
printf("%d'th characters printed on the screen before '%%n'", i);
}
output:
100 123.230000
15'th characters printed on the screen before '%n'(with new character).
We can assign the of i in an another way...
As we know the argument of print function:-
int printf(char *control-string, ...);
So, it returns the number the number of characters output. We can assign that return value to i.
#include <stdio.h>
int main()
{
int i;
i = printf("%d %f\n", 100, 123.23);
printf("%d'th characters printed on the screen.", i);
}
%n is C99, works not with VC++.