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

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

Related

When inputting large numbers it returns the final result as NaN

I am creating a SUPER basic calculator in C for a project.
/*
Declare and initialize variables and/or constants using appropriate data types -- X
Read in input from the user and output data & information to the user in a meaningful manner -- X
Use the mathematical operators – addition, subtraction, multiplication, division, and modulus (remainder)
– in expressions and calculations -- X
Use decision making structures such as if, if/else, and switch to affect program flow -- X
Use control structures such a while, do-while, and for loops to implement repetition in code -- X
*/
//All libraries
#include <stdio.h>
#include <stdbool.h>
#include <ctype.h>
float num1 = 0;
float num2 = 0;
float finalResult = 0;
char operator = '+';
bool opReal = false;
int main() {
//Ask for first number
printf("Enter an number: ");
scanf("%f", &num1);
printf("\n");
//Ask for second number
printf("Enter another number: ");
scanf("%f", &num2);
printf("\n");
//Ask for operator
do {
printf("Enter either + - * or /: ");
scanf(" %c", &operator);
//Check for what operator is
if (operator == '-') {
operator = '-';
opReal = true;
} else if (operator == '+') {
operator = '+';
opReal = true;
} else if (operator == '*') {
operator = '*';
opReal = true;
} else if (operator == '/') {
operator = '/';
opReal = true;
} else {
operator = '+';
opReal = false;
}
} while (!opReal);
printf("num1: %f\n", num1);
printf("num2: %f\n", num2);
printf("operator: %c\n", operator);
//Do calculations
if (operator == '-') {
finalResult = num1 - num2;
} else if (operator == '+') {
finalResult = num1 + num2;
} else if (operator == '*') {
finalResult = num1 * num2;
} else if (operator == '/') {
finalResult = num1 / num2;
}
printf("Final Result: %f\n", finalResult);
}
I've tried looking up different solutions and applying different ways to operate on num1 and 2, but in the end they don't work.
It should take num1 and num2 and apply operator to it.
However when a large number is applied then num1 = inf and num2 = inf.
That in turn makes finalResult Nan
Whats happening?
Please help.
Well depending on how large those large numbers are, you might just be able to replace "float" with "double" and have it work.
Other than that you could add the following check to your code:
if(isinf(num1) || isinf(num2) || isnan(num1) || isnan(num2)) {
printf("Error, number out of bounds!");
return -1;
}
Though this requires the use of #include <math.h> though, if you are constrained to just the libraries specified in this file (as might be implied by the comment) then this might just be an unsolvable problem.
I don't see anything particular wrong with your code so maybe you just need to switch from float to double or even long double? Don't use global variable unless you have to. Guard against divide by zero. No point of checking if an operator is x then assign x to the operator. Check that scanf() was successful otherwise you may be operating on uninitialized data.
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
int main() {
double num1;
printf("Enter a number: ");
if(scanf("%lf", &num1) != 1) {
printf("scanf failed\n");
return 1;
}
double num2;
printf("Enter another number: ");
if(scanf("%lf", &num2) != 1) {
printf("scanf failed\n");
return 1;
}
char operator;
do {
printf("Enter either + - * or /: ");
if(scanf(" %c", &operator) != 1) {
printf("scanf failed\n");
return 1;
}
} while (!strchr("-+*/", operator));
double finalResult = 0;
if (operator == '-') {
finalResult = num1 - num2;
} else if (operator == '+') {
finalResult = num1 + num2;
} else if (operator == '*') {
finalResult = num1 * num2;
} else if (operator == '/') {
finalResult = num2 != 0 ? num1 / num2 : 0; // or ERR?
}
printf("Final Result: %lf\n", finalResult);
}
I would use an array of numbers, dedup the input with a loop and probably a switch instead of all those if-else-if:
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#define NUM_LEN 2
int main() {
const char *prompts[NUM_LEN] = { "an", "another" };
double num[NUM_LEN];
for(size_t i = 0; i < NUM_LEN; i++) {
printf("Enter %s number: ", prompts[i]);
if(scanf("%lf", &num[i]) != 1) {
printf("scanf failed\n");
return 1;
}
}
char operator;
do {
printf("Enter either + - * or /: ");
if(scanf(" %c", &operator) != 1) {
printf("scanf failed\n");
return 1;
}
} while (!strchr("-+*/", operator));
switch(operator) {
case '-':
num[0] -= num[1];
break;
case '+':
num[0] += num[1];
break;
case '*':
num[0] *= num[1];
break;
case '/':
num[0] = num[1] != 0 ? num[0] / num[1] : 0; // or ERR?
break;
default:
printf("Invalid operator\n");
break;
}
printf("Final Result: %lf\n", num[0]);
}
The next step would be to build a map from operator to a function, i.e:
struct operators {
char operator;
int (*evaluate)(double *num);
} operators[] = {
{'+', add},
{'-', subtract},
{'*', multiply},
{'/', divide}
};
Now you extract the valid operators used in strchr() from this map, and you can use lfind() to lookup the evaluate function for a given operator.

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 can't my calculator program calculate operator / aka. divsision properly?

#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 =='^' ){

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
$

Resources