I was writing a simple program to read a string and then print it.
#include<stdio.h>
// void printString(char *str){
// while(*str!='\0'){
// printf("%c",*str);
// str++;
// }
// printf("\n");
// }
int main(){
char str[50];
printf("Enter Your Name:-");
scanf("%s",&str); // scanf adds '\0' automatically at the end.
char *ptr = str;
// printString(ptr);
printf("Your Name is %s%s",ptr);
return 0;
}
I wrote the above code. At first I didn't know that scanf stops when encounters a space. So I thought that I need to have two %s for printing two words but when I got to know the former part about scanf. I understood the problem but in the process, I encountered another problem which I think is unexpected behavior.
OUTPUT:-
Enter Your Name:-Rachit Mittal
Your Name is Rachit Mittal
This Output, from my understanding is unexpected.
If scanf only reads till it encounter space or new line then string contains only "RACHIT" So in the output screen even after using double %s, It should only print "Rachit" instead of "Rachit Mittal"
I wanna ask why is this so? Is this unexpected behavior because of double %s or something else?
You are invoking undefined behavior by not passing enough arguments to printf. %s%s contains two format specifiers, so printf expects two string arguments to be passed, but you only gave one. In this case, the result could be anything.
Consider enabling warnings to help diagnose these errors (e.g. compiling with -Wall).
You have two %s in the format string, but only one additional argument. So there's no argument corresponding to the second %s. This causes undefined behavior. This means that anything can happen, so nothing should be "unexpected".
It's a bit surprising that this causes it to print the second name from the input. The register or memory location that would have contained an additional argument just happened to point to the remainder of the input buffer used by stdio. This is purely coincidence.
For starters the second argument expression in this call of scanf
scanf("%s",&str);
is incorrect. The type of the expression &str is char ( * )[50] while the conversion specifier %s expects an argument of the type char *. You have to write
scanf( "%s", str );
As for your problem then according to the C Standard (7.21.6.1 The fprintf function)
2 The fprintf function writes output to the stream pointed to by
stream, under control of the string pointed to by format that
specifies how subsequent arguments are converted for output. If
there are insufficient arguments for the format, the behavior is
undefined. If the format is exhausted while arguments remain, the
excess arguments are evaluated (as always) but are otherwise ignored.
The fprintf function returns when the end of the format string is
encountered.
You could write to read several words
scanf( "%49[^\n]", str );
I need to clear all lines between StartLine and ScreenHight in c, But i get the compiler error:
warning: too many arguments for format [-Wformat-extra-args]
Code:
void clearScreen(int startLine, int screenHight)
{
for (int i=startLine; i<screenHight - 1; ++i)
{
printf("\x1b[",i,";1H\33[2K");
}
}
The first argument of printf is a format string. Your format string "\x1b[" does not have any format specifiers, so printf won't expect any of the other arguments you provided. Thus, it will only print the format string.
To specify the other two arguments, use %d (to print the integer i) and %s (to print the string ";1H\33[2K"):
printf("\x1b[%d%s",i,";1H\33[2K");
You were trying to contcatenate a string for using as a paremeter in the
printf call. But that is not how you craete a string in c.
Use another way to build your string parameter (e.g. sprintf) and
then use that string as a parameter to the printf call.
This question already has answers here:
Behaviour of printf when printing a %d without supplying variable name
(6 answers)
Closed 4 years ago.
I stumbled upon this C code in a college test and when I tested it on Dev-C++ 5.11 compiler, it printed random characters. I can't understand how or why this code works. Can someone enlighten me?
int main() {
char a[10] = "%s" ;
printf( a ) ;
}
This question has two parts: the missing quotes and the random characters.
printf() is just a function. You can pass strings and other values to functions as arguments. You don't have to use a literal. You can use both char *a = "something"; printf(a) (passing a variable as an argument) and printf("something") (passing a string literal as an argument).
printf() is also a variadic function. This means it can accept any number of arguments. You can use printf("hello world"), printf("%s", "hello world") and even printf("%s %s", "hello", "world"). Some older compilers don't verify you actually passed the right number of arguments based on the first argument which is the format string. This is why your code compiles even though it's missing an argument. When the program runs the code goes over the format string, sees "%s" and looks for the second argument to print it as a string. Since there is no second argument it basically reads random memory and you get garbage characters.
printf function signature is:
int printf(const char *format, ...);
It expects format string as the first argument and variable number of arguments that are handled and printed based on the format specifiers in the format string. variable a in your question is providing it the format string. Reason for random characters is that the argument for format specifier %s is missing. Following will correctly print a string:
printf( a, "Hello World!" );
A list of format specifiers can be seen here https://en.wikipedia.org/wiki/Printf_format_string
Why does it compile?
Because variadic arguments accepted by printf are processed at run time. Not all compilers do compile time checks for validating arguments against the format string. Even if they do they would at most throw a warning, but still compile the program.
It's using the string "%s" as a format string, and using uninitialized memory as the "data".
The only reason it does "something" is because the compiler was apparently not smart enough to recognize that the format string required one parameter and zero parameters were supplied. Or because compiler warnings were ignored and/or errors were turned off.
Just an FYI for anybody who bumps into this: "Always leave all warnings and errors enabled and fix your code until they're gone" This doesn't guarantee correct behaviour but does make "mysterious" problems less likely.
Can anyone please explain what will be the output and how? I am unable to understand the printf() function arguments. I want to know the difference between
1 and 2, and 3 and 4 printf() statements. Normally in printf(), we should give control string as first argument. But even though interchanging arguments, will I get the same output?
#include <stdio.h>
int main()
{
char *str;
str = "%s";
printf("%s\n", str); //.....1
printf(str, "%s\n"); //.......2
printf(str, "K\n"); //.......3
printf("K\n", str); //........4
return 0;
}
It is better to put the code into a compiler and look at the output. It will probably give better insight of things than asking in Stack Overflow.
The expected output is:
[%s\n] because str contains %s and it will be printed as is.
[%s\n] because str contains the format and the second argument will be printed. This form is very dangerous if str comes from the user.
[K\n] same as 2.
[K\n] str is ignored. gcc will warn you if configured correctly through command-line arguments.
Conclusion — always use #1.
The printf function arguments are comprised of
(1) an initial shift state
(2) format string
(3) list of arguments
In your case you have:
printf("%s\n",str); //.....1
No shift, a format string that takes the sting str = %s and prints it literally.
printf(str, "%s\n");//.......2
The values of str has no numeric shift (again 0) and a literal %s which is printed.
printf(str, "K\n"); //.......3
Here again you have a value of str and initial shift 0, but include a literal format string K which is printed.
printf("K\n",str); //........4
Finally, you have a format string with an insufficient number of conversion specifiers which generates the warning:
foo.c:11:1: warning: too many arguments for format [-Wformat-extra-args]
printf("K\n",str); //........4
but which contains the literal format string K which again is printed. In sum the output of the code being:
%s
%s
K
K
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++.