Fundamentals of character scanning from user in C - c

Hi this question might look kinda stupid, but I am facing some serious lack of fundamentals here which i cannot figure out. This is a very simple code for scanning four characters but it wont work properly. This is an extract from a larger program, but this is where I am facing the problem. Can anyone point out where the blunder is being made?
#include<stdio.h>
#include<stdlib.h>
{
char a, b, c, d;
printf("Enter the value of a\n");
scanf("%c", &a);
if(a == 'Y')
{
printf("Enter if this question is stupid or no Y/N\n");
scanf("%c", &b);
}
else
{
printf("This is such a big waste of time");
}
printf("Enter the value of c\n");
scanf("%c", &c);
if(c == 'Y')
{
printf("Enter if I am stupid or no? Y/N\n");
scanf("%c", &d);
}
else
{
printf("I will go mad soon\n");
}
}

I think it is possible that you have problems because of newline character. Try using
scanf(" %c", &var)
Note: My original answer was wrong but accepted, I copied this solution from #teppic.

The %c specifier tells scanf to read one character only. When you type a character and press enter, you're providing two. So the next call already has a character to read.
In order to get this work properly you need to skip any whitespace before you read a character. Change each call like this:
scanf(" %c", &a)
Now any previous newline you entered will be skipped.

You are not flushing your buffer after scanning the character, when You enter a character and press ENTER then in next scan your ENTER is treated as a character that's why it is skipping the second scan. Use any one of these __fpurge(stdin), fpurge(stdin) after each scan, whatever works on your system. It will work.

Related

Error in C simple program [duplicate]

This question already has answers here:
C: Multiple scanf's, when I enter in a value for one scanf it skips the second scanf [duplicate]
(7 answers)
Closed 8 years ago.
This is part of a university lab and the TA tells me there is an error but I haven't a clue. When I run it it asks me for the first char but then runs through the program and doesn't ask me at the second scanf.
#include <stdio.h>
int main(void) {
char sen, ben;
printf("Type in a character: ");
scanf("%c", &sen);
printf("The key just accepted is %d", sen);
printf("\nType in another character: ");
scanf("%c", &ben);
printf("The key just accepted is %d", ben);
}
Actually this is C not C++. Save it as file.c.
Try this:
#include <stdio.h>
int main(void) {
char sen, ben;
printf("Type in a character: ");
sen = getchar();
printf("The key just accepted is %d", sen);
printf("\nType in another character: ");
getchar();
ben = getchar();
printf("The key just accepted is %d", ben);
}
Explanation: when you enter the first character and press enter it takes enter's ASCII code as the second.
I suggest not to use scanf. But it works both ways if you put a getchar to "take" the enter.
Adding a space before %c in the second scanf will solve the issue.
This is done because scanf does not consume the \n character after you enter the first character and leaves it in the stdin.As the Enter key(\n) is also a character,it gets consumed by the next scanf call.The space before the %c will discard all blanks like spaces.
When you are scanning a character(%c) using scanf,add a space before %c as it would help reduce confusion and help you. Therefore, in both the scanfs , you can add the space.
When you pressed your key and then hit enter, you typed in two keys. The first was the desired key ,a for example, and the second was the key <enter> typically written as \n. So, your second scanf captures the result \n.
Since printing out the \n character doesn't result in something that is easy to see on the screen, it will appear like your program is just skipping the second scanf and printing out only the fixed parts of the printf without a easily viewable value.
One way to get around this problem is to consume all the key strokes just before the key you want to capture. This is done by accepting more input after the character up until you see a newline character \n. Once you see that character, then you do your next read.
// flush extra input up the to carriage return
char flush = 0;
while (flush != '\n') {
scanf("%c", &flush);
}
// now read my desired input
scanf("%c", &ben);
that's because nobody accepts '\n'. call scanf like this scanf("%c%*c", &sen). %*c means you want to omit one character, which is '\n'.
btw, void main() is allowed. main function is not the real entry point of executable, so it's ok to do that. but it seems not everybody likes it.

how to use scanf to get input to include space

I am new to C this is something I have always been confused about
let's say I have a code like this
I only want to use char
char a, b, c;
printf("input first character: ");
scanf(" %c", &a);
printf("input second character: ");
scanf(" %c", &b);
printf("input thrid character: ");
scanf(" %c", &c);
how ever I want to be able to read in space as well; I noticed how this would only read in non-space characters, what if I want to read space as well something like this c=' '; how do I scan this space in;
now by listening to suggestion of using getchar() I wrote this :
#include<stdio.h>
int main(void)
{
char a,b,c;
printf("input the first char:");
a=getchar();
printf("input the second char:");
b=getchar();
printf("input the third char:");
c=getchar();
return 0;
}
how ever something strange happens when I compile and run the program
the program output is like this
input the first char:
input the second char:input the third char:
now it never let me to input the second char it jumped straight to the third request at the end I was only asked to enter 2 inputs which is very strange because the program clearly asked for 3 in the code.
now here is a program I wrote like this I added what is suggested into the code block
int main(void)
{
int totalHeight=0, floorWidth=0, amountOfStories, amountWindowForTop, amountWindowForMiddle, amountWindowForBottom, windowHeight, middleWindowWidth, topWindowWidth, bottomWindowWidth, minimumHeight, minimumWidth;
int betweenDistanceTop, betweenDistanceMiddle, betweenDistanceBottom, edgeDistanceTop, edgeDistanceBottom, edgeDistanceMiddle;
char topFloorWindowContent, middleFloorWindowContent, bottomFloorWindowContent, windowBorder, floorBorder;
int tempMax, tempValue, tempSideDistance, tempBetweenDistance;
printf("please enter how many stories your building would like to have: ");
scanf("%d",&amountOfStories);
minimumHeight=amountOfStories*6+1;
while((totalHeight<minimumHeight)||((totalHeight%amountOfStories)!=1))
{
printf("please enter the totalHeight (minimum %d): ",minimumHeight);
scanf("%d",&totalHeight);
}
printf("please enter how many window building would have for top floor: ");
scanf("%d",&amountWindowForTop);
printf("please enter how many window building would have for middle floors: ");
scanf("%d",&amountWindowForMiddle);
printf("please enter how many window building would have for bottom floor: ");
scanf("%d",&amountWindowForBottom);
tempMax=amountWindowForTop;
if (tempMax<amountWindowForMiddle)
{
tempMax=amountWindowForMiddle;
}
if (tempMax<amountWindowForBottom)
{
tempMax=amountWindowForBottom;
}
while(floorWidth<tempMax)
{
printf("please enter the width of the building (Minimum %d): ",tempMax*4+1);
scanf("%d",&floorWidth);
}
char a, b, c;
printf("a:");
a=getchar();getchar();
printf("b:");
b=getchar();getchar();
printf("c:");
c=getchar();
printf("a=%c, b=%c, c=%c", a, b, c);
return 0;
}
now here is the funny part if I put this block of code in the big program it doesn't work the output is something like this
please enter how many stories your building would like to have: 2
please enter the totalHeight (minimum 13): 2
please enter the totalHeight (minimum 13): 2
please enter the totalHeight (minimum 13): 13
please enter how many window building would have for top floor: 2
please enter how many window building would have for middle floors: 2
please enter how many window building would have for bottom floor: 2
please enter the width of the building (Minimum 9): 9
a:
b:*
c:a=
, b=
, c=
as we can see a b c all read in \n instead of the space * and c didn't even read anything at all Why is that ?
The problem with your code is this: when you read the first char (a), you press enter (\n) for insert the next char, so now on stdin there is a \n that you haven't readed. When you try to read the next character, (b) the program read the previous \n from stdin and does not allow you to read the next char. So, when you read a char with getchar() and then press enter on the keyboard, you need a second getchar() for remove the \n.
Here is a sample code that could solve your issue:
#include<stdio.h>
int main(void) {
char a, b, c;
printf("a:");
a=getchar();getchar();
printf("b:");
b=getchar();getchar();
printf("c:");
c=getchar();
printf("a=%c, b=%c, c=%c", a, b, c);
return 0;
}
For the edited you posted, you need to put what is called "the stdin cleaner" before taking the value for a,b,c:
while(getchar()!='\n');
it just reomove all characters till \n.
Please, take note that when programs like the one you posted has a lot of input from keyboard, sometime you get this issue because there are extra chars in stdin. So the general answer for this issue will be try to figure out where these extra chars (mostly there is an extra \n somewhere) could be and use a function like the one i mentioned to remove so that you can continue reading from stdin.
You should use getchar()
a = getchar();
scanf will not scan anything until you give any data so it is not useful to scan ' ' char.
for this you have to use getchar() fun for char or gets() for string, it will scan data until you give enter. it will comes out even if either you have not provided any char, or simple ' ' char.
If u want to read the character with space then you may use the gets() functtion.
char str[10];
str=gets();
try scanf("%c", &ch).
as stated in scanf format specifier:
"Whitespace character: the function will read and ignore any whitespace characters encountered before the next non-whitespace character (whitespace characters include spaces, newline and tab characters -- see isspace). A single whitespace in the format string validates any quantity of whitespace characters extracted from the stream (including none)."
getchar() gets unexpected result because in windows, newline(when you hit Enter in console) is two characters.

My C do while loop will not execute

My program assignment is to write a looping program that calculates USD to Euros. My code looks like this
#include <stdio.h>
int main(void)
{
double USD, euro;
char again;
do
{
printf("Please enter the amount of USD you want to convert to Euros> ");
scanf_s("%lf", &USD);
euro=USD * 0.73209;
printf("%4.2f USD equals %4.2f Euros.", USD, euro);
printf("Do you want to convert another amount (y/n)?");
scanf_s("%c", &again);
}
while (again == 'y' || again == 'Y');
return 0;
}
And when I run the program, it executes, allows my to enter a USD value, gives me the correct Euro value, then when prompt for y/n it just exits.
As other folks have explained, your problem is due to \n remaining in STDIN.
In order to skip it, just replace
scanf_s("%c", &again);
with
scanf_s(" %c", &again);
This is part of scanf's functionality:
White-space characters: blank (' '); tab ('\t'); or newline ('\n'). A white-space character causes scanf to read, but not store, all consecutive white-space characters in the input up to the next non–white-space character. One white-space character in the format matches any number (including 0) and combination of white-space characters in the input.
http://msdn.microsoft.com/en-us/library/kwwtf9ch.aspx
For your first scanf,
scanf(" %lf", &USD);
may also help.
This is because that there are stray \r and or \n left in your input stream (stdin), which is read by scanf and gets out of the do while, replace your scanf_s line with
while((again = getchar()) != '\n' && again != EOF);
if you want to use scanf_s then you can do something like
do {scanf_s("%c", &again);}while(again == '\n' || again == '\r');
For more information about this check http://c-faq.com/stdio/gets_flush2.html
I think you must use strcmp() here.
while ( strcmp(again, 'y') == 0 || strcmp(again, 'Y') == 0 )
I'm about two weeks into learning C so sorry if it doesn't work!
Try this.
#include <stdio.h>
int main(void)
{
double USD, euro;
char again;
do
{
printf("Please enter the amount of USD you want to convert to Euros> ");
scanf_s("%lf", &USD);
getchar();
euro=USD * 0.73209;
printf("%4.2f USD equals %4.2f Euros.", USD, euro);
printf("Do you want to convert another amount (y/n)?");
again = getchar();
}
while (again == 'y' || again == 'Y');
return 0;
}
It is happening because scanf does not takes whitespace characters. like newline, space etc. when you were pressing enter 'USD' was taking the value and 'again' was taking the newline character. Hope this helps. :)
stdin (standard input) has one more character you are missing, right after you ask for the USD amount, that character don't simple goes way, as a matter of fact it's waiting for you to pull it out, and that's what you do with the last scanf. This happens because you told scanf (the first one) to read just a float (double) number and nothing else.
To see what's going on, you could check the value of the variable again as indiv said. Although it's preferable to print the ASCII value instead of the character itself, because you may not be able to really know for sure if it is an space, new line, tab or any other character of this kind.
instead try this:
printf("ASCII: %d, CHAR: %c\n", again, again);
Put that line right after the last scanf.
Either way, your problem is to find a way to discard that last character. One solution could be reading an string from stdin and then using atof() to convert that string into a decimal number.
change
scanf_s("%c", &again);
to
scanf_s("%c", &again, 1);

Problems with scanf

#include <stdio.h>
int main()
{
char C, B;
int x;
printf("What comes after G\n");
scanf("%c", &C);
printf("What comes after O\n");
scanf("%c", &B);
printf("What is your age?\n");
scanf("%d", &x);
printf("You said %c comes after G, %c after T and you're %d years old? Right?", C, B, x);
return 0;
}
The problem is whenever you run the code it skips the second question "What comes after O" and then asks "What is your age?"
The only way I could avoid the program skip the 2nd question was by adding a space to the code
printf("What comes after O\n");
scanf(" %c", &B);
You can see the space between " and %c
Can you please explain this to me?
You need to eat up the white space (i.e. new line) - as per the manual page http://linux.die.net/man/3/scanf
You can use scanf to eat the single character without assigning it to anything like this::
scanf( "%[^\n]%*c", &C ) ;
%[^\n] tells the scanf to read every character that is not '\n'. That leaves the '\n' character in the input buffer, then the * (assignment suppression) will consume the a single character ('\n') but would not assign it to anything.
The reason for this problem is newline character \n leftover by the previous scanf after pressing Enter. This \n is left for the next call of scanf.
To avoid this problem you need to place a space before %c specifier in your scanf.
scanf(" %c", &C);
...
scanf(" %c", &B);
...
scanf(" %c", &X);
A space before %c is able to eat up any number of newline characters.
The problem is you are using scanf to get the character ..and a new line will be added at the end of each input from user . So the second time only the new line will be stored in the 'B' Because of the first input given by you ..
Instead of scanf , change it to getchar - your problem should get solved

scanf() function doesn't work? [duplicate]

This question already has answers here:
C: Multiple scanf's, when I enter in a value for one scanf it skips the second scanf [duplicate]
(7 answers)
Closed 8 years ago.
This may be a simple question, but i searched a lot and still didn't figure it out.
I compiles below snip code by gcc and run program from terminal. In correct, It allow to enter an int and a char but it doesn't. It doesn't wait to enter the char??
Anyone here can help me will be kind. thanks in advance!
#include <stdio.h>
int main()
{
char c;
int i;
// a
printf("i: ");
fflush(stdin); scanf("%d", &i);
// b
printf("c: ");
fflush(stdin); scanf("%c", &c);
return 0;
}
%d will read consecutive digits until it encounters a non-digit. %c reads one character. Probably what's happening is that you're giving it a number (several digits) followed by a new line. %c then reads in that new line. You were probably intending for the fflush(stdin); to discard anything that hadn't yet been read, but unfortunately, that's undefined behavior.
The solution is to discard all whitespace before reading the character:
scanf(" %c", &c);
Note the space at the start. That means to discard all whitespace.
You can use the getchar() to achieve what you want.
or consume the extra newline by using:-
scanf(" %c", &c);
^^^ <------------Note the space
Reason:- Your next scanf for reading the character just reads/consumes the newline and hence never waits for user input
Instead of fflush(stdin); scanf("%c", &c);
1.use scanf with extra space
scanf(" %c",&c);
or
2.use getchar() two times , first time reads '\n' which is entered after giving integer input and second time call ask you for give input as c:
getchar();
c=getchar();
would help you.
First of all, scanf works when used as directed. I think the following code does what you want. Stdout is flushed so that user is prompted to enter an integer or a character. Using %1s allows white space like \n.
int main()
{
char c[2];
int i;
printf("i: ");
fflush(stdout);
scanf("%d", &i);
printf("c: ");
fflush(stdout);
scanf("%1s", &c);
printf("\ni = %d, c = %c", i, c[0]);
return 0;
}
This code was tested/run on an Eclipse/Microsoft C compiler.
That fflush() is not guaranteed to do anything, and gcc/g++ doesn't. Not on Linux, anyway.
I thought I invented the following way to flush the rest of a line...until I saw it as an example in the ISO C spec (90 or 99...forgot which, but it's been there a long time either way...and I'll bet most readers here have seen it before.)
scanf("%*[^\n]%*c"); /* discard everything up to and including the next newline */
You can put that in your own "flush" function to save typing or pasting that all over the place.
You should still follow the suggestions to to put a space in scanf(" %c", &c);.
That will patiently wait for a non-whitespace character in case of a leading space or a double hit of the enter key.

Resources