I've got a question about switch statements.
Here is my code:
#include<stdio.h>
int main()
{
float a=0.0f;
float b=0.0f;
char operation=0;
printf("Enter expression:");
scanf("%f %c %f",&a,&operation,&b);
switch(operation)
{
case '+':
printf("=%.2f\n",a+b);
break;
case '-':
printf("=%.2f\n",a-b);
break;
case '*':
printf("=%.2f\n",a*b);
break;
case '/':
if(b==0)
printf("\ndivision by zero error.\n");
else
printf("=%.2f\n",a/b);
break;
case '%':
if(b==0)
printf("\ndivision by zero error.\n");
else
printf("=%d\n",(int)a%(int)b);
break;
default:
printf("invalid operation\n");
break;
}
return 0;
}
And this is result about two different input, one right, one wrong.
Why, when I enter two letters instead of two numbers, does it go into the default case?
a+b won't match the format string of your scanf since it expects floats not chars (like a or b), therefore scanf does not do anything.
scanf returns the number of items it was able to read which will be 0 in this case. Checking its return value is not a bad idea.
And since operation is initialized to 0 the default case will execute.
scanf("%f %c %f",&a, &operation, &b);
So, when you enter a+b:
'a' is not a float
scanf fails (you can check this by looking at its return value)
operation is still with its default value which is 0
Inside the switch statement, none of the cases('+', '-', '*', '/', '%') get matched because char operation = 0;
Therefore, the default block is executed.
Because you need to check the return value of scanf
// scanf("%f %c%f", &a, &operation, &b);
if (scanf("%f %c%f", &a, &operation, &b) != 3) {
fprintf(stderr, "Unable to convert input!\n");
exit(EXIT_FAILURE);
}
Related
When I'm typing in a digit I see
Type in a digit 1
Type in an operator ERROR: Unknown operator!
accumulator = 0.000000
Type in a digit
Why step - printf("Type in an operator ") is skipped and is replaced by - default:
printf ("ERROR: Unknown operator!\n");
break;
Thanks for the help in advance!
// Program to produce a simple printing calculator
#include <stdio.h>
#include <stdbool.h>
int main (void)
{
double accumulator = 0.0, number; // The accumulator shall be 0 at startup
char operator;
bool isCalculating = true; // Set flag indicating that calculations are ongoing
printf("You can use 4 operator for arithmetic + - / *\n");
printf("To set accumulator to some number use operator S or s\n");
printf("To exit from this program use operator E or e\n");
printf ("Begin Calculations\n");
while (isCalculating) // The loop ends when operator is = 'E'
{
printf("Type in a digit ");
scanf ("%lf", &number); // Get input from the user.
printf("Type in an operator ");
scanf ("%c", &operator);
// The conditions and their associated calculations
switch (operator)
{
case '+':
accumulator += number;
break;
case '-':
accumulator -= number;
break;
case '*':
accumulator *= number;
break;
case '/':
if (number == 0)
printf ("ERROR: Division by 0 is not allowed!");
else
accumulator /= number;
break;
case 'S':
case 's':
accumulator = number;
break;
case 'E':
case 'e':
isCalculating = false;
break;
default:
printf ("ERROR: Unknown operator!\n");
break;
}
printf ("accumulator = %f\n", accumulator);
}
printf ("End of Calculations");
return 0;
}
scanf for a char consumes the newline characters. So the scanned char is "linefeed" instead of the one you're expecting.
I replaced:
scanf ("%c", &operator);
by
scanf ("%*c%c", &operator);
(consuming linefeed before the operator without assigning it using %*c format)
and your code worked fine.
I've found out that you could write the list of characters that are (not)allowed as an input when using scanf().
I need a user to type one of the following letters: d, f, r, k, c
So what i did is the following, and it works actually exactly the way i want it to. it doesn't let the program go further until one of the allowed letters is eventually pressed:
scanf ("%[^cfrdk]", &skala);
after that i want to check which of those five letter was actually entered, and here i get the whole problem. i don't get what exactly happens to the variable skala but its value is obviously not the entered letter. as i try to print it, it prints nothing. The switch-case after that also always goes by default.
here is the whole code:
int main()
{
char skala;
float inval,cels, fahr, kelvin, rankine, delis;
printf("Choose the Skala. Enter:\n`C` for Celsius"
" \n`F` for Fahrenheit \n`D` for Delisle \n`K` for Kelvin \n`R` for Rankine"
" \n Enter the letter here —> ");
scanf ("%[^cfrdk]", &skala);
getchar();
//printf("You have entered correctly. %c", &skala); PRINTS NOTHING
switch (skala){
case 'c': printf("You've chosen Celsius\n");
break;
case 'f': printf("You've chosen Fahrenheit\n");
break;
case 'r': printf("You've chosen Rankine\n");
break;
case 'd': printf("You've chosen Delisle\n");
break;
case 'k': printf("You've chosen Kelvin\n");
break;
default:printf("ERROR: wrong input\n");
break;
}
printf ("Enter a value to be converted = ");
scanf("%f", &inval);
return 0;
}`
who can explain it what exactly happens to the variable in scanf when using the list of allowed characters. And what are the ways of solving the problem?
The do/while loop will repeat until a letter in the set of valid letters is input.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
char skala;
char valid[] = "cfdkr";
float inval,cels, fahr, kelvin, rankine, delis;
int result = 0;
int clean = 0;
printf("Choose the Skala. Enter:\n`C` for Celsius"
" \n`F` for Fahrenheit \n`D` for Delisle \n`K` for Kelvin \n`R` for Rankine"
" \n Enter the letter here —> ");
do {
if ( ( result = scanf (" %c", &skala)) != 1) {
if ( result == EOF) {
fprintf ( stderr, "problem getting input\n");
return 1;
}
}
if (strchr ( valid, skala) == NULL) {
printf ( "enter your choice of %s\n", valid);
result = 0;
}
} while ( result != 1);
switch (skala){
case 'c': printf("You've chosen Celsius\n");
break;
case 'f': printf("You've chosen Fahrenheit\n");
break;
case 'r': printf("You've chosen Rankine\n");
break;
case 'd': printf("You've chosen Delisle\n");
break;
case 'k': printf("You've chosen Kelvin\n");
break;
default:printf("ERROR: wrong input\n");
break;
}
do {
printf ("Enter a value to be converted = ");
if ( ( result = scanf("%f", &inval)) != 1) {
while ( clean = getchar ( )) != '\n') {
if ( clean == EOF) {
fprintf ( stderr, "problem getting input\n");
return 1;
}
}
}
} while ( result != 1);
return 0;
}
I need a user to type one of the following letters: d, f, r, k, c
Code cannot control what the user types. Code needs to cope with unexpected input.
The below is bad code. If scanf() does encounter some non-cfrdk, it will save 1 or more of those characters into skala and then append a null character. skala being only a char, is the wrong type for reading strings - the type expected by %[]. Result: Undefined behavior (UB).
If use does type a cfrdk, then scanf ("%[^cfrdk]", &skala); will read nothing into skalla and return 0.
scanf ("%[^cfrdk]", &skala);
Better to simply read all user input. Be sure to handle '\n'
switch (getchar()){
case 'c': printf("You've chosen Celsius\n");
break;
case 'f': printf("You've chosen Fahrenheit\n");
break;
case 'r': printf("You've chosen Rankine\n");
break;
case 'd': printf("You've chosen Delisle\n");
break;
case 'k': printf("You've chosen Kelvin\n");
break;
case '\n': // ignore
break;
case EOF: // input is closed
return -1;
default: printf("ERROR: wrong input\n");
// break;
}
Even better as suggested by #hyde, read a line of user input with fgets() and then validate the input.
char buf[80];
if (fgets(buf, sizeof buf, stdin) == NULL) {
// Handle End-Of-File or Error
return -1;
}
char scale[2] = { 0 };
// Check for valid initial character, additional checks possible
if (sscanf(buf, "%1[cfrdk]") != 1) Handle_Bad_Input(buf);
else {
switch (scale[0]) {
...
i have just entered a switch case code.. i don't understand why when i am pressing '1', it is still going to the default case always.
#include <stdio.h>
int main() {
char c = 0;
int x = 0, y = 0;
printf("Please write 2 numbers:\n");
scanf("%d %d", &x, &y);
printf("Please choose an action from the math menu:\n\n1.add\n2.sub\n");
scanf(" %c", &c);
switch (c)
{
case 1:
printf("%d + %d is %d\n", x, y, x+y);
break;
default: printf("Wrong value\n");
break;
}
return 0;
}
As c is declared as having character type then entered 1 and 2 are characters correspondingly '1' and '2'.
So write
switch (c)
{
case '1':
printf("%d + %d is %d\n", x, y, x+y);
break;
case '2':
printf("%d - %d is %d\n", x, y, x-y);
break;
default: printf("Wrong value\n");
break;
}
The character 0 to 9 are actually ascii values 48 to 57. switch( (int)(c-48) ) would work. The express (int)(c-48) changes the ascii digits to integers.
An alternative to the previous answer using character literals:
switch(c)
{
case '1':
...
break;
...
}
This allows you to even handle 'q' and the like.
When doing 'q', keep in mind the case sensitivity:
switch(c)
{
case 'q':
case 'Q':
... handle q
break;
}
In short: You are reading a char, treat it as a char.
As a newbie to c programming (I've only had experience in visual basic), I'm not entirely sure how a while loop with a changing string variable in its condition statement should function.
The following code is a simple calculator that I was making that allows the user to input an operation and two numbers, then output the respective result. I'am trying to code in a while loop that continually repeats the procedure until the user decides to exit it. However it seems that the line scanf("%c", &quit); isn't affecting the while loop condition statement.
#include <stdio.h>
int main() {
float num1, num2;
char operation;
char quit = "n";
while (quit = "n"){
printf("Enter an operator (+, -, *, /) \n");
scanf(" %c", &operation);
printf("Enter the numbers you wish to carry out the operation on \n");
scanf("%f %f", &num1, &num2);
switch(operation) {
case '+':
printf("%f\n", num1+num2);
break;
case '-':
printf("%f\n", num1-num2);
break;
case '*':
printf("%f\n", num1*num2);
break;
case '/':
printf("%f\n", num1/num2);
break;
}
printf("Would you like quit the program, is so enter 'y' \n");
scanf("%c", &quit);
}
return 0;
}
Thanks for all your help in advance.
You could do like this
#include <stdio.h>
int main() {
float num1, num2;
char operation;
char quit = 'n';
//while (quit = "n") //
while (quit!= 'y')
{
printf("Enter an operator (+, -, *, /) \n");
scanf(" %c", &operation);
printf("Enter the numbers you wish to carry out the operation on \n");
scanf("%f %f", &num1, &num2);
switch(operation) {
case '+':
printf("%f\n", num1+num2);
break;
case '-':
printf("%f\n", num1-num2);
break;
case '*':
printf("%f\n", num1*num2);
break;
case '/':
printf("%f\n", num1/num2);
break;
}
printf("Would you like quit the program, is so enter 'y' \n");
scanf("%c", &quit);
}
return 0;
}
replace while (quit = "n") with while (quit! = 'y')
That's because you're assigning the value of the quit variable in your while loop, instead of checking for its value.
Use == for =
while(quit == "n"){...}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
This program simulates a simple menu driven calculator with +, -, *, and / operations
#include <stdio.h>
#include <conio.h>
int main()
{
float a = 0, b = 0;
printf(" Enter two numbers: ");
scanf(" %f %f",&a ,&b);
puts(" Enter choice number of operation: ");
puts(" 1)Addition ");
puts(" 2)Subtraction ");
puts(" 3)Multiplication ");
puts(" 4)Division ");
flushall(); //To clear the trailing '\n'
switch( getchar() - 48 )
{
case 1: printf("The Sum of %.2f and %.2f is : %.2f",a,b,(a+b));
break;
case 2: printf("The Difference of %.2f and %.2f is : %.2f",a,b,(a-b));
break;
case 3: printf("The Product of %.2f and %.2f is : %.2f",a,b,(a*b));
break;
case 4: if ( b != 0 ) printf("The Quotient of %.2f and %.2f is : %.2f",a,b,(a/b));
else puts("Error, divide by zero not possible.");
break;
default: puts("Error, Invalid choice");
}
return 0;
}
Is it better this way? As I have avoided the usage of a variable, and equivalently described why the program crashes when the last input is not a valid choice, I don't think there is any need to add info about what was entered. It adds an extra variable into the picture.
Yes, switch statement can take an expression for the value on which you switch. Your code should work fine, except that getchar() would read the leftover '\n' character from scanf of the operands.
Add another call to getchar() before the switch to read and discard that extra character.
While the code is valid and correct, I'd do the following to make it more readable:
switch(getchar()) {
case '1': // ...
case '2': // ...
case '3': // ...
case '4': // ...
}
Or
switch(getchar() - '0') {
case 1: // ...
case 2: // ...
}
This is to avoid using the magic number 48, which may not be understood easily by readers.
Furthermore, you can discard input until the next \n using a simple while loop:
while(getchar() != '\n') ;
In addition to the \n, this will also read and discard anything before the newline.
switch ( expression )
So you have a valid expression and you can have a expression like you have if you really have a need for something like this.
Else
char ch = getchar(); /* or scanf(" %c",&ch); (Better)*/
int a = ch - '0';
switch(a)
{
}
For your answer : Yes the switch can accept an expression in its arguments but it should returns only one of these types char int short long int long long int it can be also signed or unsigned !
There is no need to make a cast for the expression getchar() - 48 because getchar() returns int and 48 is an int so th result would be an int
now after compiling you have to add 3 number one for the variable a and the second for the variable b and the third for the switch statement... for instance
$./executable_file
Enter two numbers: 1 2 3
Switch formatting
This is a suggested formatting of your switch statement. I disagree with the idea of using getchar() in the switch statement (though it is technically legal, it is simply a bad idea in practice), so I've replaced that with c:
int c;
/* c is set by some input operation.
** It might be char c; if you read its value with scanf(), but it must be int if you use getchar()
*/
switch (c)
{
case 1:
printf("The Sum of %.2f and %.2f is : %.2f", a, b, (a+b));
break;
case 2:
printf("The Difference of %.2f and %.2f is : %.2f", a, b, (a-b));
break;
case 3:
printf("The Product of %.2f and %.2f is : %.2f", a, b, (a*b));
break;
case 4:
if (b != 0)
printf("The Quotient of %.2f and %.2f is : %.2f",a, b, (a/b));
else
fputs("Error, divide by zero not possible.\n", stderr);
break;
default:
fprintf(stderr, "Error, Invalid choice %c\n", c);
break;
}
Note the use of break; after the default: label too; it protects you against future additions to the code and is completely uniform. (The default: label does not have to be last, though that is the conventional place for it to go.) Commas get a space after them; so do if, for, while, switch, but function calls do not get a space between the name and the open parenthesis. You don't normally need a space after an open parenthesis or before a close parenthesis. Errors are reported to standard error.
Personally, I like the actions of the switch to be indented just one level, not two levels, so I'd use:
switch (c)
{
case 1:
printf("The Sum of %.2f and %.2f is : %.2f", a, b, (a+b));
break;
case 2:
printf("The Difference of %.2f and %.2f is : %.2f", a, b, (a-b));
break;
case 3:
printf("The Product of %.2f and %.2f is : %.2f", a, b, (a*b));
break;
case 4:
if (b != 0)
printf("The Quotient of %.2f and %.2f is : %.2f",a, b, (a/b));
else
fputs("Error, divide by zero not possible.\n", stderr);
break;
default:
fprintf(stderr, "Error, Invalid choice %c\n", c);
break;
}
Many people disagree, so you're certainly not under an obligation to do that.