I have following code:
#include <stdio.h>
int main()
{
int i;
char c;
char *format_string = "%d\n";
scanf(format_string, &i);
printf("read: %d\n", i);
printf("Let's check what is in the input buffer:\n");
while (scanf("%c", &c) == 1)
{
printf("read from input buf: %d\n", c);
}
}
If I run the code following way:
echo "5" | ./specific.out
The output is following:
read: 5
Let's check what is in the input buffer:
Here I have more general version of above code, where I pass format string from command line:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
if (argc != 2)
{
exit(EXIT_SUCCESS);
}
int i;
char c;
char *format_string = argv[1];
scanf(format_string, &i);
printf("read: %d\n", i);
printf("Let's check what is in the input buffer:\n");
while (scanf("%c", &c) == 1)
{
printf("read from input buf: %d\n", c);
}
}
If I run the code following way:
echo "5" | ./general.out '%d\n'
The output is following:
read: 5
Let's check what is in the input buffer:
read from input buf: 10
Why do I get different outputs?
When you specify '%d\n' on the command line, you're not sending a % followed by d followed by a newline. You sending % followed by d followed by \ followed by n.
Because of this, the newline generated by the echo command doesn't match anything in the format string (specifically a newline doesn't match \), so it gets left in the input buffer.
To get the same result, your command line would have to look like this:
echo "5" | ./x1 '%d
'
On a side note, it's a bad idea for a format string to be under the control of a user, as that can lead to a format string vulnerability. Format strings are best left as string literals.
As an added bonus, if you use a string literal as a format string then your compile will also be able to generate warnings if the format string doesn't match the parameters passed to it.
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