Why are the if conditions not being executed? - c

This is a menu driven program asking for user's choice.
Why are if conditions not executed?
Output is attached.
Creating a program asking for user's input:
void main()
{
float a,b,ans=0;char ch,choice;
choice='y';
while(choice=='Y'||choice=='y')
{
printf("Enter two numbers \n");
scanf("%f %f",&a,&b);
printf("1.+for Addition\n");
printf("2.-for subtraction \n");
printf("3.*for multiplication \n ");
printf("4./for Division \n");
printf("Enter your choice of operation \n");
scanf("%c",&ch);
if(ch=='+')
ans=a+b;
else if (ch=='-')
ans=a-b;
else if(ch=='*')
ans=a*b;
else if(ch=='/')
ans=a/b;
else
{
printf("wrong choice entered\n");
}
printf("Answer is %f \n",ans);
printf("Do you want to coninue (Y/N)\n");
scanf("%c",&choice);
}
printf("program Terminated\n");
}
Output:
/* Enter two numbers
1010
22
1.+for Addition
2.-for subtraction
3.*for multiplication
4./for Division
Enter your choice of operation
wrong choice entered
Answer is 0.000000
Do you want to coninue (Y/N)
n
program Terminated
*/
The above is the output screen.
It doesn't perform operations.

When you input first 2 numbers, they are placed into variables a and b. BUT after entering those 2 numbers, you pressed enter. Computer sees that as new input and place it in first next appropriate variable that requires input. In this case it's your variable ch, and instead of +,-./ or *, ch has value of "new line". If you try to write value of ch on standard output as an integer, it will write number 10. It's ASCII character of new line. Simply adding getchar() after inputting first 2 numbers will collect that new line sign, and your next scanf will work properly.
By the way, you have same problem with your last input scanf("%c",&choice); because pressing enter after previous operation decision, will also cause your program not to work properly. Do the same thing for this part, or simply leave blank character before %c.

Try the following
scanf(" %c",&ch);
^^
and
scanf(" %c",&ch);
^^
Otherwise a next character is read that can be a white space character.
Take into account that according to the C Standard function main without parameters shall be declared like
int main( void )

scanf() does not consume trailing newlines. The skipped scanf() receives the newline from the previous line typed by the user and terminates without receiving more input as you would expect...
scanf() is a bit cumbersome with newlines. A possible solution would be to use fgets() to get a line from the console and then employ sscanf() to parse the received string.
Another, more targeted, solution would be to use " %c" in the format string of the last scanf() call. The %c format specifier does not consume leading whitespace on its own, which is why it gets the remaining newline, rather than a character typed by the user.

Related

while loop code not working (keepgoing='y') [duplicate]

This question already has answers here:
scanf() leaves the newline character in the buffer
(7 answers)
Closed 3 years ago.
So I'm learning how to use the while and for loops in C but this code won't seem to work. the scanf statement seems to be getting ignored and the loop just repeats itself without requiring me to input 'Y' for it to repeat. Here's the code:
void showCommission();
void main() {
char keepGoing='y';
while(keepGoing=='y') {
showCommission();
printf("Do you want to calculate another?\n");
scanf("%c",&keepGoing);
}
}
void showCommission() {
float sales,commission;
const float COM_RATE=0.10;
printf("Enter the amount of sales\n");
scanf("%f",&sales);
commission=sales*COM_RATE;
printf("The commission is $%f.\n",commission);
}
Here's what running the code gives me:
Enter the amount of sales
5000
The commission is $500.000000.
Do you want to calclulate another?
...Program finished with exit code 10
Press ENTER to exit console.
it never prompts me to enter y and the code just exits for some reason.
The problem you're encountering is that the call to scanf to read in a value using the %c format will accept a newline character as valid input!
This, combined with the fact that the scanf("%f",&sales); call reads in a float value but does not 'consume' the following newline, will leave that newline character in the input buffer, for the subsequent call to read a value for keepGoing. Thus, you will have a value for keepGoing that is not y and the program will terminate.
There are several ways around this. The simplest, perhaps, is to add a space character before the %c field, which will instruct the scanf function to skip all 'whitespace' characters (which includes the newline) when 'scanning' for the input character:
scanf(" %c", &keepGoing); // Added space before %c will skip any 'leftover' newline!
You've got a few problems. First, you need to check your scanf return values; if stdin is closed without providing y, scanf will constantly return -1 without rewriting keepGoing (making the loop infinite).
The other problem is early exit; %c suppresses the normal scanf whitespace skipping behavior, so your scanf's in main are always trying to read whatever followed the float you just parsed to populate sales (usually whitespace or a newline of some sort), so when you enter:
1.12
y
the %c reads the newline after the 2, not the y, and the loop exits immediately.
A simple fix would be to change:
scanf("%c",&keepGoing);
to:
if (scanf(" %c", &keepGoing) != 1) break;
The leading space will reenable whitespace skipping so it consumes all whitespace before it tries to read the next character, and whenever it fails to read a character at all, it will end the loop, rather than running forever. A similar check should probably be added for your other scanf.
This is due to the newline (enter keystroke) leftover from non-chars input.
scanf("%f",&sales);
For example, if i enter 500 for the amount of sales, the program will read 500\n, where the \n is your enter keystroke. However, scanf("%f",&sales) will only read float value. Therefore the \n is leftover in your input buffer. Then, when the program try to run scanf("%c",&keepGoing), it consume the leftover \n and it will treat as you pressed enter keystroke and skipped the input.
The issue can be fixed by consuming the leftover \n.
void showCommission() {
float sales,commission;
char consumeNewLine;
const float COM_RATE=0.10;
printf("Enter the amount of sales\n");
scanf("%f",&sales);
scanf("%c",&consumeNewLine);
commission=sales*COM_RATE;
printf("The commission is $%f.\n",commission);
}

Using scanf() function two times: works in one case but not in other case [duplicate]

This question already has answers here:
scanf() leaves the newline character in the buffer
(7 answers)
Closed 3 years ago.
I'm the learning the very basics of C programming right now, and I'm practicing the scanf() function. This very, very simple program takes in a number and a letter and uses the printf() function to display the number and letter.
If I ask the user to enter the number first, the program works, i.e., asks for a number, asks for a letter, and prints the input. If I ask for the letter first, the program asks for a letter but then doesn't ask for a number.
I've tried multiple ways and reordered it, but it doesn't seem to work.
This works:
#include<stdio.h>
void main(){
int number;
char letter;
printf("Enter letter...");
scanf("%c", &letter);
printf("Enter number....");
scanf("%d", &number);
printf("Number entered: %d and letter entered: %c.\n", number, letter);
}
But, this combination doesn't work:
#include<stdio.h>
void main(){
int number;
char letter;
printf("Enter number....");
scanf("%d", &number);
printf("Enter letter...");
scanf("%c", &letter);
printf("Number entered: %d and letter entered: %c.\n", number, letter);
}
The output I get for the first program is:
Enter letter...a
Enter number....9
Number entered: 9 and letter entered: a.
Which is correct
But the second case doesn't work, and I don't get why it wouldn't work -- skips the "enter letter" part
the output is
Enter number....9
Enter letter...Number entered: 9 and letter entered:
.
Context: I entered "a" for letter and "9" for number in the above example.
It turns out there's a surprising difference between %d and %c. Besides the fact that %d scans potentially multiple digits while %c scans exactly one character, the surprising difference is that %d skips any leading whitespace, while %c does not.
And then there's another easily-overlooked issue when you're using scanf to read user inputs, which is, what happens to all those newlines -- the \n characters -- that get inserted when the user hits the ENTER key to input something?
So here's what happened. Your first program had
printf("Enter letter...");
scanf("%c", &letter);
printf("Enter number....");
scanf("%d", &number);
The user typed a letter, and ENTER, and a number, and ENTER. The first scanf call read the letter and nothing else. The \n stayed in the input stream. And then the second scanf call, with %d, skipped the \n (because \n is whitespace) and read the number, just like you wanted.
But in your second program you had the inputs in the other order, like this:
printf("Enter number....");
scanf("%d", &number);
printf("Enter letter...");
scanf("%c", &letter);
Now, the user types a number and hits ENTER, and the first scanf call reads the number and leaves the \n on the input stream. But then in the second scanf call, %c does not skip whitespace, so the "letter" it reads is the \n character.
The solution in this case is to explicitly force the whitespace-skipping that %c doesn't do by default. Another little-known fact about scanf is that a space in a format string doesn't mean "match one space character exactly", it means "match an arbitrary number of whitespace characters". So if you change your second program to:
printf("Enter number....");
scanf("%d", &number);
printf("Enter letter...");
scanf(" %c", &letter);
Now, the space character in " %c" in the second scanf call will skip over the \n that was left over after the user typed the number, and the second scanf call should read the letter it's supposed to.
Finally, a bit of editorializing. If you think this is a bizarre situation, if you think the exception to the way %c works is kind of strange, if you think it shouldn't have been this hard to read a number followed by a letter, if you think my explanation of what's going on has been far longer and more complicated than it ought to have been -- you're right. scanf is one of the uglier functions in the C Standard Library. I don't know any C programmers who use it for anything -- I don't believe I've ever used it. Realistically, its only use is for beginning C programmers to get data into their first programs, until they learn other, better ways of performing that task, ways that don't involve scanf.
So my advice to you is not to spend too much time trying to get scanf to work, or learning about all of its other foibles. (It has lots.) As soon as you're comfortable, start learning about the other, better ways of doing input, and leave scanf comfortably behind forever.
Try this
#include <stdio.h>
int main(void) {
int number;
char letter;
printf("Enter letter...");
scanf("%s", &letter);
printf("Enter number....");
scanf("%d", &number);
printf("Number entered: %d and letter entered: %c.\n", number, letter);
return 0;
}
If you change the %c to %s then you get the correct output.
Add a space before %c. So, change this:
scanf("%c", &letter);
to this:
scanf(" %c", &letter);
As I have written in caution when using scanf, this will make scanf eat the whitespaces and special characters (otherwise it will consider them as inputs).
Here, it will consume the newline character, on other words, the Enter you press, after typing your input!
To be exact, in your example, think of what the user (in this case you) do:
You type 9
You press Enter
You type 'a'
You press Enter
Now, when you input something, from your keyboard in this case, this will go into the Standard Input buffer, where it will patiently await to be read.
Here, scanf("%d", &number); will come and read a number. It finds 9 in the first cell of the STDIN buffer, it reads it, thus deleting it from the buffer.
Now, scanf("%c", &letter); comes, and it reads a character. It finds the newline character, that's the first Enter you pressed, and the function is now happy - it was told to read a character, and that's exactly what it did. Now that newline character gets deleted from the buffer (now what's left in there is 'a' and a newline character - these two are not going to be read, since there is no other function call. left for that).
So what changes if I write scanf(" %c", &letter); instead?
The first scanf will still read the number 9, and the buffer will now have a newline character, the 'a' character, and another newline character.
Now scanf(" %c", &letter);` is called, and it goes to search for a character to read in the STDIN buffer, only that now it will first consume any special characters found.
So there it goes to the buffer, it firstly encounters the newline character, it consumes it.
Then, it will encounter 'a', which is not a special character, and therefore it will read normally, and stored to the passed variable in scanf.
The last newline character will remain in the STDIN buffer, untouched and unseen, until the program terminates and the buffer gets deallocated.
Tip: You probably meant to write int main(void), instead of void main(). Read more in What should main() return in C and C++?
Specifying scanf the following way
scanf("%c", &letter);
does not skip white spaces and can read for example a new line character stored in the input buffer when the user pressed Enter entering previous data.
Use instead
scanf(" %c", &letter);
^^^
to skip white spaces.
From the C Standard (7.21.6.2 The fscanf function)
8 Input white-space characters (as specified by the isspace function)
are skipped, unless the specification includes a [, c, or n specifier.
and
5 A directive composed of white-space character(s) is executed by
reading input up to the first non-white-space character (which remains
unread), or until no more characters can be read.
Pay attention to that according to the C Standard the function main without parameters shall be declared like
int main(void)
From the C Standard (5.1.2.2.1 Program startup)
1 The function called at program startup is named main. The
implementation declares no prototype for this function. It shall be
defined with a return type of int and with no parameters:
int main(void) { /* ... */ }

Unable to Assign Value to Char Variable in below Code?

Puzzeled with this C program , This program is not asking for CHOICE as INPUT when i execute in this order but if I put Integer Input (inputNum) statement after choice asking choice input is working but then Integer Input is not taking input Value
int main()
{ int inputNum; char choice='A';
printf("Please enter number : ");
scanf("%d",&inputNum);
printf("\nEnter (N/n) to STOP ADDING : ");
scanf("%c",&choice);
printf("\nChoice is : %c\n",choice);
return 0;
}
Here's what's going on.
printf("Please enter number : ");
scanf("%d",&inputNum);
When this runs, you are prompted to enter a number, and then of course you hit return to flush the input buffer. That leaves a \n (newline) character in there, which gets read by:
printf("\nEnter (N/n) to STOP ADDING : ");
scanf("%c",&choice);
So the program goes Choice is : and leaves a blank line -- that's the \n that got put into choice.
One solution is to use;
scanf("%*c%c", &choice);
The * tells scanf() to discard the field, in this case, the newline remaining from the last input.
if I put Integer Input (inputNum) statement after choice asking choice input is working
It's important to note that the issue with the newline won't affect %d scans, because these skip leading whitespace. So if you ask for two integers in your program instead of an int and a char, it works without the need to manually skip the newline. The same logic applies to most kinds of input, as per a statement from the ISO C 99 Draft Standard repeated in the POSIX man page for fscanf:
Input white-space characters (as specified by isspace) shall be
skipped, unless the conversion specification includes a [, c, C, or n
conversion specifier.
That "unless" applies of course to %c.
The return character (pressed to validate your first input) is still present in the standard input buffer.
You can solve your issue by adding getchar(); after your first scant, as it will consume the stray \n of the buffer, leaving it empty for your next input.

Why loop is running once?

#include <stdio.h>
main()
{
int num;
char another="y";
for(;another=="y";)
{
printf("no. is ");
scanf("%d", &num);
printf("sq. of %d is %d", num,num*num);
printf("\nWant to enter another no. : y/n");
scanf("%c", &another);
}
}
I have C code like this. According to me, this should work like: Enter the no and give square. But its nor running in infinite loop. But it is running only once. Why?
I am using GCC4.8.1 compiler on windows 64 bit.
Because on second iteration scanf assign \n to anotherinstead of assigning y.
EXPLANATION: When you press Enter key after typing the input, then one more character goes to the buffer along with the typed input. This character is produced by Enter and is \n. Suppose you typed y and then pressed the Enter key then the buffer would contain y\n, i.e, two characters, y and \n.
When scanf("%d", &num); is executed then it reads the number typed in and leaves behind the \n character in the buffer for next call of scanf. This \n is read by the next scanf call scanf("%c", &another); irrespective of what you have typed in your console.
To eat up this new line char, use a space before %c specifier in scanf.
scanf(" %c", &another);
^Notice the space before %c.
And change
for(;another=="y";) {...} // Remove the double quote.
to
for(;another=='y';) {...} // Single quote is used for `char`s.
The test in the loop is wrong:
another=="y"
this compares the value of another, a single character, with the value of a string literal, which will be reprented as a pointer to the character y. It should be:
another == 'y'
You should have gotten compiler warnings for this, since it's very strange to compare a small integer with a pointer.

Why scanf is behaving weird for char input?

/* Write macro for the following :
1. Arithmetic Mean of two no.
2. Absolute value of a no.
3. To convert a Uppercase letter to lower case.
4. To obtain bigger of two numbers.
*/
#include<stdio.h>
#define am(a,b) ((a+b)/2)
#define abs(a) (a>=0?a:-a)
#define ul(ch) (ch>=65 && ch<=96 ? ch+32 : ch)
#define bigger(a,b) (a>=b?a:b)
int main () {
int x,y;
char c;
printf("\nEnter two numbers:");
scanf("%d%d",&x,&y);
printf("\nThe arithmetic mean of two numbers is %f",(float)am(x,y));
printf("\nEnter the number:");
scanf("%d",&x);
printf("\nThe absolute value of the number is %d",abs(x));
printf("\nEnter the character:");
scanf("%c",&c);
printf("\nThe letter in lower case is %c",ul(c));
printf("\nEnter two numbers:");
scanf("%d%d",&x,&y);
printf("\nThe bigger of two numbers is %d",bigger(x,y));
return 0;
}
Everything is working fine except that program does not stop for taking character input.
Here is the snapshot of the output ....
Enter two numbers:4
5
The arithmetic mean of two numbers is 4.000000
Enter the number:-7 **/*After hitting enter here it reaches line no. 7 */**
The absolute value of the number is 7
Enter the character:
The letter in lower case is
Enter two numbers:4 **/*line no. 7*/**
6
The bigger of two numbers is 6
It is because the %d skips white space, but %c does not -- or in other words.
The %d will skip any proceeding white space in your input stream, and the input pointer will be then just after the last digit -- which is most likely you newline. So when you come to ask for the %c you will actually already have input data -- that is your newline -- and that is what you will read.
change your scanf to ask it to skip white space by just inserting a space before the %c, so
scanf(" %c",&c);
I believe the problem here is that your scanf("%c",&c) is grabbing the carriage return entered when you hit enter to put in the -7.
Put a getchar (or another scanf("%c",&c)) right before the scanf and you shouldn't have that problem.
%c reads any character including whitescape, so it will "eat" the newline character.
Use: scanf(" %c",&c);
A common issue with scanf is that it doesn't consume the newline caused by pressing enter. I usually get around it by using the following macro after a call to scanf
#define consumeBuffer() while (getchar() != '\n');
Of course this is not always what you want, but for most cases it will do the trick.
That's because after your first scanf, the enter key is still in the input buffer, and the next scanf will store the enter value in x. Then your next printf will print it - effectively moving to a new line.
To fix this you can just add a getchar() call after each scanf.

Resources