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.
Related
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
I am working on building a calculator in C, and have encountered a problem regarding scanf for characters. I have defined a "string" called operationValue, but when I try to do the scanf function (the one that I have a comment right next to it), it immediately prints out an invalid character instead of the operation I typed in. I needed the string instead of just a character because I have the other operation for powers and roots, but even they don't work when I type them in. When I complete the code it prints "Not Valid Operation."
Sorry if this is not what is conventional in stack overflow, but this is the first time I'm on here. If the pieces of code are too long or something, please help me edit it so I can learn not to do that next time.
#include <stdio.h>
void theOperation(double num1, char operationValue, double num2)
{
if(operationValue == "+")
{
printf("%lf\n", num1 + num2);
} else if(operationValue == "-")
{
printf("%lf\n", num1 - num2);
} else if(operationValue == "*")
{
printf("%lf\n", num1 * num2);
} else if(operationValue == "/")
{
printf("%lf\n", num1 / num2);
} else if(operationValue == "pow")
{
printf("%lf\n", pow(num1, num2));
} else if(operationValue == "root")
{
printf("%lf\n", pow(num1, (1/num2)));
} else
{
printf("Not valid operation");
}
}
int main()
{
double num1, num2;
char operationValue[10];
printf("This is a calculator.\n");
printf("Enter first number: ");
scanf("%lf", &num1);
printf("%lf\n", num1);
printf("Enter operation: ");
scanf(" %s", &operationValue);
printf("%c\n", operationValue); // This line fails when I type in any operation I define: '+', '-', '*', '/' 'pow' 'root'
printf("Enter second number: ");
scanf("%lf", &num2);
printf("%lf\n", num2);
theOperation(num1, operationValue, num2);
return 0;
}
Use the "%s" for reading and printing the operator:
#include <stdio.h>
#include <math.h>
#include <string.h>
void theOperation(double num1, char* operationValue, double num2)
{
if(strcmp(operationValue, "+") == 0)
{
printf("%lf\n", num1 + num2);
} else if(strcmp(operationValue, "-") == 0)
{
printf("%lf\n", num1 - num2);
} else if(strcmp(operationValue,"*") == 0)
{
printf("%lf\n", num1 * num2);
} else if(strcmp(operationValue,"/") == 0)
{
printf("%lf\n", num1 / num2);
} else if(strcmp(operationValue,"pow") == 0)
{
printf("%lf\n", pow(num1, num2));
} else if(strcmp(operationValue, "root") == 0)
{
printf("%lf\n", pow(num1, (1/num2)));
} else
{
printf("Not valid operation");
}
}
int main()
{
double num1, num2;
char operationValue[10];
printf("This is a calculator.\n");
printf("Enter first number: ");
scanf("%lf", &num1);
printf("%lf\n", num1);
printf("Enter operation: ");
scanf(" %9s", &operationValue);
printf("%c\n", operationValue);
printf("Enter second number: ");
scanf("%lf", &num2);
printf("%lf\n", num2);
theOperation(num1, operationValue, num2);
return 0;
}
Scanf() docs: https://www.tutorialspoint.com/c_standard_library/c_function_scanf.htm
-- EDIT --
I have updated the code to a working one.
I also updated the scanf() for reading the operator like #M. Nejat Aydin commented for prevent buffer overrun
The code has several defects:
The function signature given:
int theOperation(num1, operationValue, num2)
is incorrect. You must define the datatype alongside the identifier.
The function returns int but nowhere used.
A variable char[10] passed into a function which accepts char, which will obviously give unexpected results.
If you want to use mathematical functions like pow(), sqrt(), floor(), etc., you must define the header file math.h. They're not available in stdio.h (that only contains I/O operation functions and subroutines).
Code redefined:
#include <stdio.h>
// return type set to: void, datatypes defined for function parameters
void theOperation(double num1, char operationValue, double num2)
{
double result = 0;
// calculating the results based on operations
switch (operationValue) {
case '+': result = num1 + num2; break;
case '-': result = num1 - num2; break;
case '*': result = num1 * num2; break;
case '/': result = num1 / num2; break;
default:
printf("No such operation found.\n");
break;
}
printf("Result: %lf\n", result);
}
int main(void)
{
double num1, num2;
char operationValue;
printf("This is a calculator.\n");
printf("Enter first and second number: ");
scanf("%lf %lf", &num1, &num2);
printf("%lf %lf\n", num1, num2);
printf("Enter operation: ");
scanf(" %c", &operationValue);
printf("%c\n", operationValue);
// the operation execution
theOperation(num1, operationValue, num2);
return 0;
}
The explanation is pretty much simple.
The scanf() takes the necessary data from the user and then passes the parameters to the function theOperation() with their appropriate arguments. Thereafter, the switch statements tries to match which expression is given in case statements are identical to the operationValue.
When it does finds one, it simply evaluates the expression and prints the result.
Note: If you just want to compare single letters like +, -, *, /, etc. then you still don't need to use character array to compare them using strcmp() or anything.
It gives the following output:
This is a calculator.
Enter first and second number: 10 50
10.000000 50.000000
Enter operation: -
-
Result: -40.000000
%c in scanf() is for reading one character. You should use %(max length)s to read strings (that don't contain whitespace characters). The (max length) should be buffer size minus one (for terminating null-character). Also note that %(max length)s will take char*, so you shouldn't put & before arrays.
%c in printf() is for printing one character. You should use %s to print strings.
#include <stdio.h>
int main()
{
double num1, num2;
char operationValue[10];
printf("This is a calculator.\n");
printf("Enter first number: ");
scanf("%lf", &num1);
printf("%lf\n", num1);
printf("Enter operation: ");
scanf(" %9s", operationValue);
printf("%s\n", operationValue);
printf("Enter second number: ");
scanf("%lf", &num2);
printf("%lf\n", num2);
return 0;
}
It wasn't too hard to fix your code by adding types and ensuring the arguments get passed through correctly:
#include <stdio.h>
#include <stdlib.h>
void theOperation(double num1, char operationValue, double num2)
{
switch (operationValue) {
case '+':
printf("%lf\n", num1 + num2);
break;
case '-':
printf("%lf\n", num1 - num2);
break;
case '/':
printf("%lf\n", num1 / num2);
break;
case '*':
printf("%lf\n", num1 * num2);
break;
default:
printf("Not valid operation");
}
}
int main()
{
double num1, num2;
char operationValue;
printf("This is a calculator.\n");
printf("Enter first number: ");
scanf("%lf", &num1);
printf("%lf\n", num1);
printf("Enter operation: ");
scanf(" %c", &operationValue);
printf("%c\n", operationValue);
printf("Enter second number: ");
scanf("%lf", &num2);
printf("%lf\n", num2);
theOperation(num1, operationValue, num2);
return 0;
}
I made fixes in function parameters, strings vs. chars and wrong scanf format chars, taking all your operations including "pow" and "root" and combining it with switch():
#include <stdio.h>
#include <math.h>
#include <string.h>
void theOperation(double num1, const char *operationValue, double num2)
{
switch(*operationValue) {
case '+': printf("%lf\n", num1 + num2); break;
case '-': printf("%lf\n", num1 - num2); break;
case '*': printf("%lf\n", num1 * num2); break;
case '/': printf("%lf\n", num1 / num2); break;
default: {
if(!strcmp(operationValue, "pow")) {
printf("%lf\n", pow(num1, num2));
} else if(!strcmp(operationValue, "root")) {
printf("%lf\n", pow(num1, (1/num2)));
} else printf("Not valid operation\n");
break;
}
}
}
int main()
{
double num1, num2;
char operationValue[10];
printf("This is a calculator.\n");
printf("Enter first number: ");
scanf("%lf", &num1);
printf("%lf\n", num1);
printf("Enter operation: ");
scanf("%9s", operationValue);
printf("operation entered: %s\n", operationValue);
printf("Enter second number: ");
scanf("%lf", &num2);
printf("%lf\n", num2);
theOperation(num1, operationValue, num2);
return 0;
}
Output example with "power":
$ gcc -Wall -o calc calc.c ;./calc
This is a calculator.
Enter first number: 2
2.000000
Enter operation: pow
operation entered: pow
Enter second number: 3
3.000000
8.000000
This is an important line:
scanf("%9s", operationValue);
(Read a string with up to 9 chars.)
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
$
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"){...}
i m new in programing.
i've written a simple program.
i want to repeat the program again and again and it can only exit when user wants to exit.
here is my program
#include<stdio.h>
#include<conio.h>
main()
{
char ch;
int num1, num2, a, m, s, choice;
float d;
printf("\nEnter The First Number: ");
scanf("%d", &num1);
printf("\nEnter The Second Number: ");
scanf("%d", &num2);
a=num1+num2;
m=num1*num2;
s=num1-num2;
d=(float)(num1/num2);
printf("\nEnter Your Choice \nFor Addition Type A \nFor Multipication Type M \nFor Division Type D \nFor Substraction Type S : ");
scanf(" %c", &ch);
switch(ch)
{
case 'A': printf("\nThe Addition Of The Number Is= %d", a);
break;
case 'M': printf("\nThe Multipication Of The Numbers Is= %d", m);
break;
case 'S': printf("\nThe Substraction Of THe Numbers Is= %d", s);
break;
case 'D': printf("\nThe Division Of The Two Numbers Is= %f", d);
break;
default : printf("\nInvalid Entry");
break;
}
printf("\nPress Any Key To Exit");
getch();
return 0;
}
and here is the output
"Enter The First Number: 10
Enter The Second Number: 10
Enter Your Choice
For Addition Type A
For Multipication Type M
For Division Type D
For Substraction Type S : A
The Addition Of The Number Is= 20
Press Any Key To Exit"
I want a line before the line Press Any Key To Exit
"If You Want To Calculate Again Press Y
or
Press Any Key To Exit"
when press Y then the program should start from the beginning.
How can i do this???
wrap the code inside a do{} while() ?
char answer;
do{
printf("\nEnter The First Number: ");
scanf("%d", &num1);
printf("\nEnter The Second Number: ");
scanf("%d", &num2);
a=num1+num2;
m=num1*num2;
s=num1-num2;
d=(float)(num1/num2);
printf("\nEnter Your Choice \nFor Addition Type A \nFor Multipication Type M \nFor Division Type D \nFor Substraction Type S : ");
scanf(" %c", &ch);
switch(ch)
{
case 'A': printf("\nThe Addition Of The Number Is= %d", a);
break;
case 'M': printf("\nThe Multipication Of The Numbers Is= %d", m);
break;
case 'S': printf("\nThe Substraction Of THe Numbers Is= %d", s);
break;
case 'D': printf("\nThe Division Of The Two Numbers Is= %f", d);
break;
default : printf("\nInvalid Entry");
break;
}
printf("\nPress Y to continue. Press any Key To Exit");
scanf(" %c",&answer); // dont forget type &
}
while(answer == 'y' || answer == 'Y');
Declare a variable, let's say answer, which will store the user answer when you ask for "Press Y to continue. Press any Key To Exit". Check to see what value has that variable. If is 'y' or 'Y', the loop will repeat. If the user pressed other key, the loop is over.
You can also use recursion, which is often used in more functional oriented programming languages.
Pseudo-code:
myfunction = do
...
b <- somethingtodo
...
if b
then myfunction
else return ()
Relative to Jens's solution, it would look like:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int main (void)
{
char choice;
int num1, num2, cont;
printf("Enter the first number: ");
scanf("%d", &num1);
getchar ();
printf("Enter the second number: ");
scanf("%d", &num2);
getchar ();
printf("A - addition\n");
printf("S - subtraction\n");
printf("M - multiplication\n");
printf("D - division\n");
printf("[ASMD]? ");
choice = (char)toupper(getchar());
getchar ();
printf("\n");
switch(choice)
{
case 'A':
printf("%d + %d = %d", num1, num2, num1 + num2);
break;
case 'S':
printf("%d - %d = %d", num1, num2, num1 - num2);
break;
case 'M':
printf("%d * %d = %d", num1, num2, num1 * num2);
break;
case 'D':
if (num2 == 0)
fprintf(stderr, "The divisor can not be zero");
else
{
printf("%d / %d = %f", num1, num2, (double)num1 / num2);
}
break;
default :
fprintf(stderr, "Invalid entry");
break;
}
printf("\n");
for (;;)
{
printf("Continue [YN]? ");
cont = toupper(getchar());
getchar ();
if (cont == 'Y')
return main(); // the difference.
else if (cont == 'N')
return EXIT_SUCCESS;
}
}
I would move the calculation stuff in it's own function and then use while() in main.
I have tried to fix other problems as well (this solution only uses standard C functions).
#include <stdio.h> // puts, printf, fprintf, scanf, getchar, stderr, EOF
#include <stdlib.h> // exit, EXIT_SUCCESS, EXIT_FAILURE
#include <ctype.h> // toupper
char fail_on_eof (int c)
{
if (c == EOF)
exit (EXIT_FAILURE);
// In case of fail_on_eof (scanf (...)) the return value of this this
// function is not useful
// scanf () returns the number of chars read or EOF
// getchar () returns a char or EOF
return (char) c;
}
void skip_to_next_line (void)
{
char c;
do
{
c = fail_on_eof (getchar ());
} while (c != '\n');
}
char read_upcase_char_line (char* prompt)
{
char c;
printf ("%s ", prompt);
c = fail_on_eof (toupper (getchar ()));
skip_to_next_line ();
return c;
}
int read_num_line (char* prompt)
{
int num;
printf ("%s ", prompt);
fail_on_eof (scanf ("%d", &num));
skip_to_next_line ();
return num;
}
int calculate (void)
{
char choice;
int num1, num2, cont;
num1 = read_num_line ("Enter the first number:");
num2 = read_num_line ("Enter the second number:");
puts("A - addition");
puts("S - subtraction");
puts("M - multiplication");
puts("D - division");
choice = read_upcase_char_line ("[ASMD]?");
puts("");
switch(choice)
{
case 'A':
printf("%d + %d = %d", num1, num2, num1 + num2);
break;
case 'S':
printf("%d - %d = %d", num1, num2, num1 - num2);
break;
case 'M':
printf("%d * %d = %d", num1, num2, num1 * num2);
break;
case 'D':
if (num2 == 0)
// Better use stderr for error messages
fprintf(stderr, "The divisor can not be zero");
else
{
printf("%d / %d = %f", num1, num2, (double)num1 / num2);
}
break;
default :
// Better use stderr for error messages
fprintf(stderr, "Invalid entry");
break;
}
printf("\n");
for (;;)
{
cont = read_upcase_char_line ("Continue [YN]?");
if (cont == 'Y')
return -1;
else if (cont == 'N')
return 0;
}
}
int main(void)
{
while (calculate ());
return EXIT_SUCCESS; // Use this constant to avoid platform specific issues with the return code
}