Difference between scanf("%c", &c) and scanf(" %c", &c) [duplicate] - c

This question already has answers here:
Why does a space in my scanf statement make a difference? [duplicate]
(3 answers)
Closed 9 years ago.
Consider the following C code snippet:
#include <stdio.h>
int main()
{
int a;
char c;
scanf("%d",&a);
scanf("%c",&c);
printf("int=%d\n",a);
printf("char=%c\n",c);
}
I'm able to input only the integer and not the character.The output is simply the integer value and no value is output for the second printf statement.
However if I use a space before the format specifier:
scanf(" %c",&c);
It works as expected. Why is this the case?
Someone told me it has something to do with clearing the input buffer. Could someone shed some light on the same?

The difference between scanf("%c", &c1) and scanf(" %c", &c2) is that the format without the blank reads the next character, even if it is white space, whereas the one with the blank skips white space (including newlines) and reads the next character that is not white space.
In a scanf() format, a blank, tab or newline means 'skip white space if there is any to skip'. It does not directly 'clear the input buffer', but it does eat any white space which looks similar to clearing the input buffer (but is quite distinct from that). If you're on Windows, using fflush(stdin) clears the input buffer (of white space and non-white space characters); on Unix and according to the C standard, fflush(stdin) is undefined behaviour.
Incidentally, if you typed the integer followed immediately by a carriage return, the output of your program ends with two newlines: the first was in c and the second in the format string. Thus, you might have seen:
$ ./your_program
123
int=123
char=
$
That is, the scanf() reads the newline as its input. Consider an alternative input:
$ ./your_program
123xyz
int=123
char=x
$
The integer input stopped when it read the 'x'; the character input therefore reads the 'x'.

Because after you input the number and press ENTER, the new line stays in the buffer and will be processed by the second scanf.
In short, you saved new line in the variable c.
However ,if you use
scanf(" %c",&c);
// ^
the space will consume the new line, which makes c the value you expected.

You have to pass a pointer to the data object specified by the format string, so
scanf("%c", c);
will actually pass the value of c, which in turn could cause a program fault,
scanf("%c", &c);
will pass the address of c, allowing scanf to change the value of your copy.
The space after the %c will force it to look for a character, AND THEN a space. If there is not a space, it will not read the character

Related

C Programing : scanf statement is not working in goto [duplicate]

This question already has answers here:
scanf() leaves the newline character in the buffer
(7 answers)
Closed 6 years ago.
I have this block of code (functions omitted as the logic is part of a homework assignment):
#include <stdio.h>
int main()
{
char c = 'q';
int size;
printf("\nShape (l/s/t):");
scanf("%c",&c);
printf("Length:");
scanf("%d",&size);
while(c!='q')
{
switch(c)
{
case 'l': line(size); break;
case 's': square(size); break;
case 't': triangle(size); break;
}
printf("\nShape (l/s/t):");
scanf("%c",&c);
printf("\nLength:");
scanf("%d",&size);
}
return 0;
}
The first two Scanf's work great, no problem once we get into the while loop, I have a problem where, when you are supposed to be prompted to enter a new shape char, it instead jumps down to the printf of Length and waits to take input from there for a char, then later a decimal on the next iteration of the loop.
Preloop iteration:
Scanf: Shape. Works Great
Scanf: Length. No Problem
Loop 1.
Scanf: Shape. Skips over this
Scanf: length. Problem, this scanf maps to the shape char.
Loop 2
Scanf: Shape. Skips over this
Scanf: length. Problem, this scanf maps to the size int now.
Why is it doing this?
scanf("%c") reads the newline character from the ENTER key.
When you type let's say 15, you type a 1, a 5 and then press the ENTER key. So there are now three characters in the input buffer. scanf("%d") reads the 1 and the 5, interpreting them as the number 15, but the newline character is still in the input buffer. The scanf("%c") will immediately read this newline character, and the program will then go on to the next scanf("%d"), and wait for you to enter a number.
The usual advice is to read entire lines of input with fgets, and interpret the content of each line in a separate step. A simpler solution to your immediate problem is to add a getchar() after each scanf("%d").
The basic problem is that scanf() leaves the newline after the number in the buffer, and then reads it with %c on the next pass. Actually, this is a good demonstration of why I don't use scanf(); I use a line reader (fgets(), for example) and sscanf(). It is easier to control.
You can probably rescue it by using " %c" instead of "%c" for the format string. The blank causes scanf() to skip white space (including newlines) before reading the character.
But it will be easier in the long run to give up scanf() and fscanf() and use fgets() or equivalent plus sscanf(). All else apart, error reporting is much easier when you have the whole string to work with, not the driblets left behind by scanf() after it fails.
You should also, always, check that you get a value converted from scanf(). Input fails — routinely and horribly. Don't let it wreck your program because you didn't check.
Try adding a space in the scanf.
scanf(" %d", &var);
// ^
// there
This will cause scanf() to discard all whitespace before matching an integer.
Use the function
void seek_to_next_line( void )
{
int c;
while( (c = fgetc( stdin )) != EOF && c != '\n' );
}
to clear out your input buffer.
The '\n' character is still left on the input stream after the first call to scanf is completed, so the second call to scanf() reads it in. Use getchar().
When you type the shape and ENTER, the shape is consumed by the first scanf, but the ENTER is not! The second scanf expects a number so, the ENTER is skipped because is considered a white space, and the scanf waits for a valid input ( a number) that, again, is terminated by the ENTER. Well, the number is consumed, but the ENTER is not, so the first scanf inside the while uses it and your shape prompt is skipped... this process repeats. You have to add another %c in the scanfs to deal with the ENTER key. I hope this helps!
You can also use
scanf("%c%*c", &c);
to read two characters and ignore the last one (in this case '\n')

I got an error reading a character on C [duplicate]

This question already has answers here:
Why does scanf ask twice for input when there's a newline at the end of the format string?
(7 answers)
Closed 5 years ago.
I want to read a single character from the console, but when I do, the program reads characters yet and I must write another character to save the first and finish its execution.
Code:
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
char peps;
int main(int argc, char const *argv[]) {
printf("write a character:\n");
scanf(" %c\n", &peps);
printf("%c\n", peps);
return 0;
}
Can anyone explain why it does that and how to correct this error?
If you remove the \n from the scanf(), it should work as you want.
ie, do
scanf(" %c", &peps);
instead of
scanf(" %c\n", &peps);
This is because the \n in the scanf() format string is telling the computer to read and ignore all white spaces (including \n) after reading a character.
So all white spaces including the newlines given by typing the enter key, would be ignored. This will stop only when a non-white space character is encountered which won't be read and would thus remain in the input buffer.
So, in your case, a character would first be read and it would wait for a non-white space character before executing the printf() following the scanf(). The non-white space character would remain in the input buffer and was not read and is hence not printed at once. It would be read only upon reading from the stdin again.
If you want to explore this further, consider placing that scanf() and printf() in a loop and examine the output.
Note that replacing that \n with a space would have the same effect.
ie,
scanf(" %c\n", &peps);
and
scanf(" %c ", &peps);
would have the same behavior.
What's the behavior of scanf when the format string ends with a newline?
Behaviour of scanf when newline is in the format string

what is the wrong in using two scanf(%s) simultaneously [duplicate]

This question already has answers here:
scanf: "%[^\n]" skips the 2nd input but " %[^\n]" does not. why?
(6 answers)
Closed 6 years ago.
why second scanf doesnt take any input ? does %s cancatanae the string?
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
int main()
{
char string1[50];
char string2[50];
scanf("%[^\n]s",string1);
scanf("%[^\n]s",string2);
printf("\nfirst string :%s \n",string1);
printf("\nsecnd string :%s \n",string2);
return 0;
}
input : this is bbc [enter]
output: first string :this is bbc
second string:{some characters symbol}
"%[^\n]s" tells to scanf to "eat" all the character that aren't a newline and put them in the argument; this means that, after the first scanf returns, it is leaving the newline that made it stop in the read buffer. The next scanf finds it and immediately stops reading - after all, you told it to read up to the first newline!
A solution here can be to use "%[^\n]s\n", which "eats" even the newline that follows the string, or even "%[^\n]s ", where the space is "magic", in that it tells scanf to eat all the other whitespace it can find, which includes newlines (notice however that this is a bad idea if you want to be able to read an empty string in the next line).
Even simpler, you can simply use fgets(string1, sizeof(string1), stdin), which, unlike scanf with %s, is safe against buffer overflows (yes, you can make even %s safe, but it's more work). Notice that fgets puts even the trailing newline into your string.
The problem is that your scanf format string requires the string to end in s: %[^\n] is interpreted as the format specifier, and then you have an s which must be matched by the input. Since the second string does not start in s, the second scanf reads nothing.
Replacing s with a space will fix the problem:
scanf("%[^\n] ", string1);
// ^
// Space is important
Even better, put space in front of %[^\n] in the second scanf:
scanf("%49[^\n]", string1);
scanf(" %49[^\n]", string2);
Since your string buffers have limited capacity, putting a limit of 49 is necessary to avoid buffer overruns.
Your code will only read one input. As %[^\n]s fails to read an 's'
Replace two scanf() statement with following one.
Just executed your code on my system it works.
scanf("%[^\n]s %[^\n]s",string1,string2);
Or just remove s from your statements and add space.
scanf("%[^\n] ",string1);
scanf("%[^\n] ",string2);
checked with your input for both the string and it displays the proper output.

Creating a C face program, but it only takes 2 inputs instead of 3. Why? [duplicate]

This question already has answers here:
C: function skips user input in code
(2 answers)
Closed 8 years ago.
So for a class I am taking I have to learn C and one program I am trying to make is a simple print face program that takes 3 inputted characters and uses them to create a face.
However, whenever I run it, it asks for the eye character, then prints out the "Enter nose character: " but never takes any input, instead skipping right to the mouth character. I have looked over the code and cannot figure out what is causing this.
#include <stdio.h>
void PrintFace(char eye, char nose, char mouth) {
printf("\n %c %c\n", eye, eye); // Eyes
printf(" %c\n", nose); // Nose
printf(" %c%c%c%c%c\n",
mouth, mouth, mouth, mouth, mouth); // Mouth
return;
}
int main() {
char eyeInput;
char noseInput;
char mouthInput;
// Get character for eyes
printf("Enter eye character: ");
scanf("%c", &eyeInput);
// Get character for nose
printf("Enter nose character: ");
scanf("%c", &noseInput);
// Get character for mouth
printf("Enter mouth character: ");
scanf("%c", &mouthInput);
// Print the face using the entered characters
PrintFace(eyeInput, noseInput, mouthInput);
return 0;
}
This is the output I get:
Enter eye character: o
Enter nose character: Enter mouth character: l
o o
lllll
It seems to skip the second scan statement but I can't see why. :/
Because the input stream is line-buffered, you need to press Enter after typing in the character. Now scanf reads a single character from the stream. However, there's still a newline in the stream, and that gets picked up on the next read.
One approach is to use fgets and read a whole line of text, then pick out the first character. However, doing this properly might be a little over the top.
It might be easier if you just use code to ignore characters up until the newline, as suggested here: C code for ignoring the enter key after input. Also, you should consider using getchar or getc instead of scanf. Just make a simple function to do all this stuff, and call it whenever you want to read a character.
The carriage return you're passing by hitting "Enter" after your first character is considered a second character input. Notice the difference in carriage returns in your output.
See the linked question at: C: function skips user input in code
If I remember well, scanf does not take '\n' in a string. So you put for example "dog" as a first entry but you type an enter at the end. So the second scanf take that '\n' in the buffer shiting your program. Solution? Clean up your buffer. If you are over windows fflush() can save you, using fflush(stdin) after each scanf. Over unix fflush() does not work like that and you have to do it manually. An easy way is to put a getc() or something like that that consumes that '\n'

C: Multiple scanf's, when I enter in a value for one scanf it skips the second scanf [duplicate]

This question already has answers here:
scanf() leaves the newline character in the buffer
(7 answers)
Closed 6 years ago.
I have this block of code (functions omitted as the logic is part of a homework assignment):
#include <stdio.h>
int main()
{
char c = 'q';
int size;
printf("\nShape (l/s/t):");
scanf("%c",&c);
printf("Length:");
scanf("%d",&size);
while(c!='q')
{
switch(c)
{
case 'l': line(size); break;
case 's': square(size); break;
case 't': triangle(size); break;
}
printf("\nShape (l/s/t):");
scanf("%c",&c);
printf("\nLength:");
scanf("%d",&size);
}
return 0;
}
The first two Scanf's work great, no problem once we get into the while loop, I have a problem where, when you are supposed to be prompted to enter a new shape char, it instead jumps down to the printf of Length and waits to take input from there for a char, then later a decimal on the next iteration of the loop.
Preloop iteration:
Scanf: Shape. Works Great
Scanf: Length. No Problem
Loop 1.
Scanf: Shape. Skips over this
Scanf: length. Problem, this scanf maps to the shape char.
Loop 2
Scanf: Shape. Skips over this
Scanf: length. Problem, this scanf maps to the size int now.
Why is it doing this?
scanf("%c") reads the newline character from the ENTER key.
When you type let's say 15, you type a 1, a 5 and then press the ENTER key. So there are now three characters in the input buffer. scanf("%d") reads the 1 and the 5, interpreting them as the number 15, but the newline character is still in the input buffer. The scanf("%c") will immediately read this newline character, and the program will then go on to the next scanf("%d"), and wait for you to enter a number.
The usual advice is to read entire lines of input with fgets, and interpret the content of each line in a separate step. A simpler solution to your immediate problem is to add a getchar() after each scanf("%d").
The basic problem is that scanf() leaves the newline after the number in the buffer, and then reads it with %c on the next pass. Actually, this is a good demonstration of why I don't use scanf(); I use a line reader (fgets(), for example) and sscanf(). It is easier to control.
You can probably rescue it by using " %c" instead of "%c" for the format string. The blank causes scanf() to skip white space (including newlines) before reading the character.
But it will be easier in the long run to give up scanf() and fscanf() and use fgets() or equivalent plus sscanf(). All else apart, error reporting is much easier when you have the whole string to work with, not the driblets left behind by scanf() after it fails.
You should also, always, check that you get a value converted from scanf(). Input fails — routinely and horribly. Don't let it wreck your program because you didn't check.
Try adding a space in the scanf.
scanf(" %d", &var);
// ^
// there
This will cause scanf() to discard all whitespace before matching an integer.
Use the function
void seek_to_next_line( void )
{
int c;
while( (c = fgetc( stdin )) != EOF && c != '\n' );
}
to clear out your input buffer.
The '\n' character is still left on the input stream after the first call to scanf is completed, so the second call to scanf() reads it in. Use getchar().
When you type the shape and ENTER, the shape is consumed by the first scanf, but the ENTER is not! The second scanf expects a number so, the ENTER is skipped because is considered a white space, and the scanf waits for a valid input ( a number) that, again, is terminated by the ENTER. Well, the number is consumed, but the ENTER is not, so the first scanf inside the while uses it and your shape prompt is skipped... this process repeats. You have to add another %c in the scanfs to deal with the ENTER key. I hope this helps!
You can also use
scanf("%c%*c", &c);
to read two characters and ignore the last one (in this case '\n')

Resources