Why can't my calculator program calculate operator / aka. divsision properly? - c

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
void run_calc();
void scandata(char *op, double *operand);
void do_next_op(char op, double operand, double *sum);
int main()
{
run_calc();
return 0;
}
void run_calc(){
double sum, operand;
char op, answer;
printf("Press enter to use the calculator\n");
scanf("%c", &answer);
while(answer!='q'&& answer!='Q')
{
printf("Enter an operator (+,-,/,#,^,*) and optional operand.Enter 'h' for help. Enter 'q' to exit the program.");
scandata(&op, &operand);
do_next_op(op, operand, &sum);
printf("Result so far is: %1.2lf \n", sum);
}
}
void scandata(char *op, double *operand) {
scanf(" %c", op);
if(*op =='+' || op == '-' || op == '*' || op =='/' || op =='^' ){
scanf ("%lf", operand);
}
}
void do_next_op(char op, double operand, double *sum)
{
switch(op)
{
case '+': *sum += operand; break;
case '-': *sum -= operand; break;
case '*': *sum *= operand; break;
case '/': *sum = (operand == 0) ? *sum : *sum / operand; break;
case '^': *sum = pow(*sum,operand); break;
case '#': *sum = (*sum >= 0) ? sqrt(*sum) : *sum; break;
case '%': *sum *= *sum -1; break;
case '!': *sum = (1 / *sum); break;
case '#': *sum = log(*sum); break;
case 'q': printf(" The final value of akku is %1.2lf \n", *sum); exit(0); defult: break;
}
}
Here is the conversaton when i input /2 which should give me 5 but it give me 2
Press enter to use the calculator
Enter an operator (+,-,/,#,^,*) and optional operand.Enter 'h' for help. Enter 'q' to exit the program.+5
Result so far is: 5.00
Enter an operator (+,-,/,#,^,*) and optional operand.Enter 'h' for help. Enter 'q' to exit the program.+5
Result so far is: 10.00
Enter an operator (+,-,/,#,^,*) and optional operand.Enter 'h' for help. Enter 'q' to exit the program./2
Result so far is: 2.00
Enter an operator (+,-,/,#,^,*) and optional operand.Enter 'h' for help. Enter 'q' to exit the program.Result so far is: 2.00
Enter an operator (+,-,/,#,^,*) and optional operand.Enter 'h' for help. Enter 'q' to exit the program.
How can i make it calculate correctly? and if an user input /0, i want the program to just print Result so far of sum, if not then just *sum/operand.
I think i did it right but i cant see the issue here. can someone help me?

In this line
if(*op =='+' || op == '-' || op == '*' || op =='/' || op =='^' ){
You dereferenced op to compare with '+', but didn't dereference that to compare with other things.
Have it dereference for the other operators will improve the behavior.
if(*op =='+' || *op == '-' || *op == '*' || *op =='/' || *op =='^' ){

Related

passing argument 1 and 2 of ‘strcmp’ makes pointer from integer without a cast [-Wint-conversion]

Hello so I've been working a little prgramme which is sort of a calculator (I'm a beginner) and well as you can see in the tittle at then end of the code, the two if strcmp doesn't work. And vscode is telling me (for the strcmp) Exception has occurred. Segmentation fault. But gcc is telling me what is in the tittle.
#include <stdio.h>
#include <string.h>
int main()
{
float num1;
float num2;
float anwser;
int rnum = 1;
int hi = 0;
char operator;
char ifyorn;
char y = 'y';
char n = 'n';
while (hi == 0)
{
printf("Enter operator +, -, /, x: ");
scanf(" %c", &operator);
printf("Enter num %d :", rnum++);
scanf("%f", &num1);
printf("Enter num %d :", rnum++);
scanf("%f", &num2);
switch (operator)
{
case '+':
anwser = num1 + num2;
printf("Do you want to continue y/n \n");
scanf(" %c", &ifyorn);
break;
case '-':
anwser = num1 - num2;
printf("Do you want to continue y/n \n");
scanf(" %c", &ifyorn);
break;
case 'x':
anwser = num1 * num2;
printf("Do you want to continue y/n \n");
scanf(" %c", &ifyorn);
break;
case '/':
anwser = num1 / num2;
printf("Do you want to continue y/n \n");
scanf(" %c", &ifyorn);
break;
default:
printf("This is not a valid character please try again :(");
break;
}
if(strcmp (ifyorn, n) == 0)
{
printf("%f", anwser);
hi == 1;
}
if(strcmp (ifyorn, y) == 0)
{
hi == 0;
}
}
}
The variables ifyorn, y and n are declared having the type char.
char ifyorn;
char y = 'y';
char n = 'n';
The function strcmp expects arguments of the pointer type char * that point to strings.
So these if statements
if(strcmp (ifyorn, n) == 0)
and
if(strcmp (ifyorn, y) == 0)
are incorrect. Instead you should write
if ( ifyorn == n )
and
if ( ifyorn == y )
Also instead of assignments you are using the comparison operator in these statements
hi == 1;
and
hi == 0;
You need to write
hi = 1;
and
hi = 0;
Increasing the variable rnum looks senseless
printf("Enter num %d :", rnum++);
scanf("%f", &num1);
printf("Enter num %d :", rnum++);
scanf("%f", &num2);
Why not just to write
printf("Enter num %d :", 1 );
scanf("%f", &num1);
printf("Enter num %d :", 2 );
scanf("%f", &num2);
And in the code snippet under the label default you should add one more statement
default:
printf("This is not a valid character please try again :(");
ifyorn = y;
break;
You don't have to be mean to the guy ,he is learning.
You are getting this error because you are passing characters to strcmp() instead of pointers to characters.
Here is more information regarding that function.
https://www.programiz.com/c-programming/library-function/string.h/strcmp

Why do I get, variable is not initialized error?

#include <stdio.h>
#include <conio.h>
void Calculator();
void main()
{
Calculator();
getch();
}
void Calculator()
{
int n,j;
char f1;
double t;
printf("please enter two numbers");
scanf("%d%d",&n,&j);
printf("please enter the syboml you want ( * / + or -)");
scanf("%c",&f1);
if( f1 == '+')
t = n + j;
if (f1 == '-')
t = n-j;
if (f1 == '*')
t = n*j;
if (f1 == '/')
t = n/j;
printf("%f" ,t);
}
In your final printf, you are using t that has never been initialized, and might hold a garbage value if no-one of those if conditions is met.
Consider initializing t (a simple = 0 does the job) or add an else clause somewhere
Edit:
While I was at it, I also made some changes to make sure the second scanf ignores the trailing /n without using fflush.
Edit 2:
As suggested by HAL9000, assuming that an initialization to 0 would be enough is wrong. I modified the second part of the program to make use of a switch-case and eventually reject an invalid operator.
The final code looks like this
#include <conio.h>
#include <stdio.h>
void Calculator();
int main() {
Calculator();
getch();
return 0;
}
void Calculator() {
int n, j;
char f1;
double t;
printf("please enter two numbers: ");
scanf("%d%d", &n, &j);
printf("please enter the symbol you want ( * / + or -): ");
scanf(" %c", &f1);
switch (f1) {
case '+':
t = n + j;
break;
case '-':
t = n - j;
break;
case '*':
t = n * j;
break;
case '/':
t = (float)n / j;
break;
default:
printf("Invalid symbol, please use ( * / + or -)\n");
return;
}
printf("%f\n", t);
}
In some compilers, you might be getting this t is not initialized error as your code will never ask please enter the symbol you want ( * / + or -) because scanf("%c",&f1); will take input as trailing newline char, so t never gets initialized. I ran your code in GCC compiler on mac but got output as 0.0000 as t will never be initialized in your case.
You can just eat up the trailing char for that you can use getchar(); or you can also put a space in the format string, e.g. scanf(" %c",&f1); to consume the newline character.
void Calculator()
{
int n,j;
char f1;
double t;
printf("please enter two numbers");
scanf("%d%d",&n,&j);
printf("please enter the syboml you want ( * / + or -)");
scanf(" %c",&f1);
if( f1 == '+')
t = n + j;
if (f1 == '-')
t = n-j;
if (f1 == '*')
t = n*j;
if (f1 == '/')
t = n/j;
printf("%f" ,t);
}
Not every program path leads to the assignment of the t variable. So it can be used in the printf not initialized.
switch(f1)
{
case '+':
t = n + j;
break;
case '-':
break;
t = n-j;
case '*':
t = n*j;
break;
case '/':
t = n/j;
break;
default:
t = 0;
break;
}
Now t will always will be assigned with the value.
Some additional remarks:
Always check the return value of the scanf
Your main definition is invalid. If main does not take any parameters is has to be int main(void)

How to restart main() from the beginning on an error condition?

#include <stdio.h>
int main()
{
printf("Hi!\nWelcome!\nThis is an expression based calculator\ndeveloped by Sankasuvra Bhattacharya\n");
printf("that performs arithmetic operations on\ntwo numbers.\n");
float num1;
float num2;
float ans = 0.0;
char symbol;
char ask;
printf("Please type the expression you want to calculate: ");
if(scanf("%f%1s%f",&num1,&symbol,&num2) != 3)
{
printf("\nInvalid input! Please try again...\n\n");
/* want to restart main() again here */
}
else {
switch(symbol) {
case '+' : ans = num1 + num2;
break;
case '-' : ans = num1 - num2;
break;
case '*' :
case 'x' :
ans = num1 * num2;
break;
case '/' :
if(num2 == 0) {
printf("Division by zero is not possible!\nPlease try again...\n\n");
return main();
}
else {
ans = num1 / num2;
break;
}
default :
printf("\nInvalid input! Please try again...\n\n");
return main();
}
printf("The answer is %g\n",ans);
printf("\nTo use the calculator again, type 'Y'. ");
printf("To exit, type any other character...\n");
scanf("%s",&ask);
if (ask == 'y' || ask == 'Y') {
printf("\n");
main();
}
else {
printf("Thank you for using the program. Please give full marks.");
}
}
return 0;
}
To answer your question.
I would not recommend calling main.
You could create another function that has all you code.
Inside main, you call that function.
You can call a function inside that function (called recursion)
However, a simple loop could do the job.
do{
printf("Hi!\nWelcome!\nThis is an expression based calculator\ndeveloped by Sankasuvra Bhattacharya\n");
printf("that performs arithmetic operations on\ntwo numbers.\n");
float num1;
float num2;
float ans = 0.0;
char symbol;
char ask;
printf("Please type the expression you want to calculate: ");
if(scanf("%f%1s%f",&num1,&symbol,&num2) != 3)
{
printf("\nInvalid input! Please try again...\n\n");
}
else {
switch(symbol) {
case '+' : ans = num1 + num2;
break;
case '-' : ans = num1 - num2;
break;
case '*' :
case 'x' :
ans = num1 * num2;
break;
case '/' :
if (num2 == 0) {
printf("Division by zero is not possible!\nPlease try again...\n\n");
return main();
}
else {
ans = num1 / num2;
break;
}
default :
printf("\nInvalid input! Please try again...\n\n");
return main();
}
printf("The answer is %g\n",ans);
printf("\nTo use the calculator again, type 'Y'. ");
printf("To exit, type any other character...\n");
scanf("%s",&ask);
printf("\n");
}while(ask == 'y' || ask == 'Y') ;
printf("Thank you for using the program. Please give full marks.");
}
Edit: To answer the comment to this question what you want to do is:
while(scanf("%f%1s%f",&num1,&symbol,&num2) != 3)
{
printf("\nInvalid input! Please try again...\n\n");
}
And remove the else
EDIT2: Full code. Note that the expression cannot be more than 99 characters.
#include <stdio.h>
int main()
{
float num1;
float num2;
float ans = 0.0;
char symbol;
char ask;
char string[100];
do{
printf("Hi!\nWelcome!\nThis is an expression based calculator\ndeveloped by Sankasuvra Bhattacharya\n");
printf("that performs arithmetic operations on\ntwo numbers.\n");
printf("Please type the expression you want to calculate: ");
while(1){
fgets (string , 100 ,stdin);
if(sscanf( string, "%f%1s%f",&num1,&symbol,&num2)!=3)
printf("\nInvalid input! Please try again...\n\n");
else
break;
}
switch(symbol) {
case '+' : ans = num1 + num2;
break;
case '-' : ans = num1 - num2;
break;
case '*' :
case 'x' :
ans = num1 * num2;
break;
case '/' :
if (num2 == 0) {
printf("Division by zero is not possible!\nPlease try again...\n\n");
return main();
}
else {
ans = num1 / num2;
break;
}
default :
printf("\nInvalid input! Please try again...\n\n");
return main();
}
printf("The answer is %g\n",ans);
printf("\nTo use the calculator again, type 'Y'. ");
printf("To exit, type any other character...\n");
scanf("%s",&ask);
printf("\n");
}while(ask == 'y' || ask == 'Y') ;
printf("Thank you for using the program. Please give full marks.");
return 0;
}
#Kristjan Kica answer is good. I think you are using spaces in your input like 1 + 2.
According to manual page of scanf
All conversions are introduced by the % (percent sign) character. The format string may also contain other characters. White space
(such as blanks, tabs, or newlines) in the format string match any amount of white space, including none, in the input. Everything else
matches only itself. Scanning stops when an input character does not match such a format character. Scanning also stops when an input
conversion cannot be made.
Remove the spaces and try again.
Example:
1+2 should work by the changes mentioned in kristijan answer.
Edit:
Replace the line in #Kristjan Kica answer
while(ask == 'y' || ask == 'Y') ;
with
}while(ask == 'y' || ask == 'Y') ;
Edit 2:
Last closing } should be your main functions closing brace.
Finally solved it. All thanks to Kristjan Kica...
#include <stdio.h>
int main(void)
{
float num1;
float num2;
float ans;
char symbol;
char ask;
char string[100];
fflush(stdin);
printf("Hi!\nWelcome!\nThis is an expression based calculator\ndeveloped by
Sankasuvra Bhattacharya\n");
printf("that performs arithmetic operations on\ntwo numbers.\n");
printf("Please type the expression you want to calculate: ");
fgets (string , 100 ,stdin);
if(sscanf( string, "%f%1s%f",&num1,&symbol,&num2)!=3)
{
printf("\nInvalid input! Please try again...\n\n");
main();
}
else
{
switch(symbol) {
case '+' : ans = num1 + num2;
break;
case '-' : ans = num1 - num2;
break;
case '*' :
case 'x' :
ans = num1 * num2;
break;
case '/' :
if (num2 == 0) {
printf("Division by zero is not possible!\nPlease try again...\n\n");
return main();
}
else {
ans = num1 / num2;
break;
}
default :
printf("\nInvalid input! Please try again...\n\n");
return main();
}
printf("The answer is %g\n",ans);
printf("\nTo use the calculator again, type 'Y'. ");
printf("To exit, type any other character...\n");
scanf("%s",&ask);
printf("\n");
if (ask == 'y' || ask == 'Y')
{
main();
}
else {
return 0;
}
}
}

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