A simple “printing” calculator - c

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.

Related

Why is the default case matched in this switch statement?

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);
}

C. after using scanf() with the list of allowed characters, can't get the value of the entered character

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]) {
...

Struggling to program a simple calculator

I am trying to program a simple calculator. Here is my code first:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char operator = 0;
float num1 = 0.0;
float num2 = 0.0;
float sol = 0.0;
while (operator != 'q') {
printf("Operator: ");
scanf("%c", &operator);
printf("First Number: ");
scanf("%f", &num1);
printf("Second Number: ");
scanf("%f", &num2);
switch (operator)
{
case '+': sol = num1 + num2; break;
case '-': sol = num1 - num2; break;
case '*': sol = num1 * num2; break;
case '/': sol = num1 / num2; break;
case 'q': printf("Finished!"); exit(0);
default: printf("Error!"); exit(0);
}
printf("The solution is: %.2f\n\n", sol);
}
return 0;
}
So for me the code is fine. As you can see I did this with a while loop that lets you calculate until you type in 'q' as operator. The first run of the loop works fine but then it gets creepy (my console):
Operator: +
First Number: 5
Second Number: 4
The solution is: 9.00
Operator: First Number:
Why does the program not let me enter an operator in the second loop run?
Most format specifiers with scanf will skip leading whitespace. %c does not.
scanf("%f", &num2); at the end of the first iteration leaves a newline in the input buffer.
scanf("%c", &operator); at the start of the second iteration, reads the newline and proceeds.
using a space before %c in scanf(" %c", &operator); will allow %c to skip the leading whitespace and capture the operator.
You should check scanf for errors:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char operator = 0;
float num1 = 0.0;
float num2 = 0.0;
float sol = 0.0;
while (operator != 'q') {
printf("Operator: ");
if((scanf(" %c", &operator)) != 1){
printf("Error, Fix it!\n");
exit(1);
}
printf("First Number: ");
if((scanf("%f", &num1)) != 1){
printf("Error, Fix it!\n");
exit(1);
}
printf("Second Number: ");
if((scanf("%f", &num2)) != 1){
printf("Error, Fix it!\n");
exit(1);
}
switch (operator){
case '+': sol = num1 + num2; break;
case '-': sol = num1 - num2; break;
case '*': sol = num1 * num2; break;
case '/': sol = num1 / num2; break;
case 'q': printf("Finished!"); exit(0);
default: printf("Error!"); exit(0);
}
printf("The solution is: %.2f\n\n", sol);
}
return 0;
}
and as you can see I changed scanf("%c", &operator); to this scanf(" %c", &operator); to make scanf to ignore (skip) Whitespace.

Error with this code?

So, I don't see what is flawed with my logic on this problem.
It reads the expression from left to right, and operands are floating point numbers.
However, my program gets stuck in the loop. It reads and assigns the final number, for example it assigns 10.5 to num1, but it never exits the loop.
int main(void)
{
float num1, num2;
char oper = 0;
printf("Enter an expression: ");
scanf("%f", &num1);
while (oper != ('\n' || EOF))
{
oper = getchar();
scanf("%f", &num2);
switch (oper)
{
case '+':
num1 += num2;
break;
case '-':
num1 -= num2;
break;
case '*':
num1 *= num2;
break;
case '/':
num1 /= num2;
break;
}
}
printf("Value of Expression: %.2f", num1);
return 0;
}
Expected output:
Enter an expression: 1+2.5*3
Value of expression: 10.5
while (oper != ('\n' || EOF)) Here, ('\n' || EOF) == 1, so the loop will not terminate unless you input the ASCII character that corresponds to 1 (which is unprintable). As Leffler points out, this should be while (oper != '\n' && oper != EOF) (though see the next point).
You check oper in your while loop before you read from it, so your while loop will terminate one step "after" the newline/EOF. The while loop should actually be:
while(1) {
oper = getchar();
if(oper == '\n' || oper == EOF) {
break; // Exit out of loop, ignoring the rest of the code inside the loop.
}
scanf("%f", &num2);
// ...
}
getchar returns an int, but oper is a char. Change oper to an int (EOF cannot be represented as a char)
Make oper an int. 255 is not equal to EOF
You need to revise the loop ending conditions. Your program is actually busy waiting for you to type another number after the first newline.
#include <stdio.h>
int main(void)
{
float num1, num2;
printf("Enter an expression: ");
if (scanf("%f", &num1) != 1)
return 1;
printf("Num1: %f\n", num1);
while (1)
{
int oper;
if ((oper = getchar()) == EOF || oper == '\n')
break;
printf("Operator: %c\n", oper);
if (scanf("%f", &num2) != 1)
break;
printf("Num2: %f\n", num2);
switch (oper)
{
case '+':
num1 += num2;
break;
case '-':
num1 -= num2;
break;
case '*':
num1 *= num2;
break;
case '/':
num1 /= num2;
break;
}
printf("num1 = %f\n", num1);
}
printf("Value of Expression: %.2f\n", num1);
return 0;
}
Note that this code checks each input operation to make sure it was successful. It also uses int oper instead of char oper to ensure that EOF is detected accurately. And the key trick is not to ask for more input after the getchar() reads the newline; your program was stuck waiting for you to type something in response to the second scanf() call. Notice how this code prints its inputs so you can tell what's going on. When a program is misbehaving, it is one of the simpler techniques to find out what's going wrong. When I saw Operator: and a blank line — and the program hanging — I knew very quickly what the trouble was.
Example run (program name: stuck):
$ ./stuck
Enter an expression: 1+2.5*3
Num1: 1.000000
Operator: +
Num2: 2.500000
num1 = 3.500000
Operator: *
Num2: 3.000000
num1 = 10.500000
Value of Expression: 10.50
$

While loop - changing string variable

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"){...}

Resources