patterncModerate
Recursive calculator in C
Viewed 0 times
recursivecalculatorstackoverflow
Problem
This is a calculator I wrote for a student's project.
It still has a problem (one that I know of), where it can't handle inputs of the form
I'd appreciate any remarks or advice on the code and possibly how to solve that problem.
Relevant inputs are using
EDIT: I fixed the problems listed above.
```
#include
#include
#include
void getInput(char * in) {
printf("> ");
fgets(in, 256, stdin);
}
int isLeftParantheses(char p) {
if (p == '(') return 1;
else return 0;
}
int isRightParantheses(char p) {
if (p == ')') return 1;
else return 0;
}
int isOperator(char p) {
if (p == '+' || p == '-' || p == '*' || p == '/') return p;
else return 0;
}
int performOperator(int a, int b, char p) {
switch(p) {
case '+': return a+b;
case '-': return a-b;
case '': return ab;
case '/':
if (b == 0) { printf("Can't divide by 0, aborting...\n"); exit(1); }
return a/b;
}
return 0;
}
char isDigit(char p) {
if (p >= '0' && p = '0' && p <= '9') return p - '0';
else return 0;
}
int isNumber(char * p) {
while(*p) {
if (!isDigit(*p)) return 0;
p++;
}
return 1;
}
int len(char * p) {
return int(strlen(p));
}
int numOfOperands(char * p) {
int total = 0;
while(*p) {
if (isOperator(*p)) total++;
p++;
}
return total+1;
}
int isMDGRoup(char * p) {
while(*p) {
if (!isDigit(p) && p != '/' && p != '')
return 0;
p++;
}
return 1;
}
int getLeftOperand(char p, char l) {
// Grab the left operand in p, put it in l,
//and return the index where it ends.
int i = 0;
// Operand is part of multi-*/ group
if (isMDGRoup(p)) {
while(1) {
if (p == '' || *p == '/') break;
l[i++] = *p++;
}
return i;
It still has a problem (one that I know of), where it can't handle inputs of the form
222... (more than one or / sign). The case 22 was solved in hackish ways.I'd appreciate any remarks or advice on the code and possibly how to solve that problem.
Relevant inputs are using
+, -, *, /, (, ), etc.EDIT: I fixed the problems listed above.
```
#include
#include
#include
void getInput(char * in) {
printf("> ");
fgets(in, 256, stdin);
}
int isLeftParantheses(char p) {
if (p == '(') return 1;
else return 0;
}
int isRightParantheses(char p) {
if (p == ')') return 1;
else return 0;
}
int isOperator(char p) {
if (p == '+' || p == '-' || p == '*' || p == '/') return p;
else return 0;
}
int performOperator(int a, int b, char p) {
switch(p) {
case '+': return a+b;
case '-': return a-b;
case '': return ab;
case '/':
if (b == 0) { printf("Can't divide by 0, aborting...\n"); exit(1); }
return a/b;
}
return 0;
}
char isDigit(char p) {
if (p >= '0' && p = '0' && p <= '9') return p - '0';
else return 0;
}
int isNumber(char * p) {
while(*p) {
if (!isDigit(*p)) return 0;
p++;
}
return 1;
}
int len(char * p) {
return int(strlen(p));
}
int numOfOperands(char * p) {
int total = 0;
while(*p) {
if (isOperator(*p)) total++;
p++;
}
return total+1;
}
int isMDGRoup(char * p) {
while(*p) {
if (!isDigit(p) && p != '/' && p != '')
return 0;
p++;
}
return 1;
}
int getLeftOperand(char p, char l) {
// Grab the left operand in p, put it in l,
//and return the index where it ends.
int i = 0;
// Operand is part of multi-*/ group
if (isMDGRoup(p)) {
while(1) {
if (p == '' || *p == '/') break;
l[i++] = *p++;
}
return i;
Solution
Things you did well on:
-
Organization
-
Use of comments
-
Using
Things that could be improved:
Compilation
-
I couldn't compile this program with this method written the way it is.
I'm going to assume that is due to the issues of you compiling it with
Refactoring
-
You could simplify down some of your loops.
Use a
Syntax
-
When you
-
You use some magic numbers.
I see you use the number 256 in some other places as well. Pull out that value into a
-
Use
-
Use a
Error handling:
-
It is more common to
-
Your program can't handle the input of non-whole numbers.
-
Your program can't handle malformed input.
-
Your program can't handle negative numbers properly
-
Your program can't handle whitespace.
-
Your program doesn't handle no input very well.
-
Your program can't handle numbers larger than the max size of an
-
Organization
-
Use of comments
-
Using
switch statements instead of multiple if-elses.Things that could be improved:
Compilation
-
I couldn't compile this program with this method written the way it is.
int len(char * p) {
return int(strlen(p));
}I'm going to assume that is due to the issues of you compiling it with
g++, and me having a strict compiler. My compiler thinks that this code is trying to make some sort of function call instead of parsing the string length to an int. Put the parentheses around the int instead, and it will work just fine.int len(char * p)
{
return (int) strlen(p);
}Refactoring
-
You could simplify down some of your loops.
int isMDGRoup(char * p) {
while(*p) {
if (!isDigit(*p) && *p != '/' && *p != '*')
return 0;
p++;
}
return 1;
}Use a
for loop here instead.int isMDGRoup(char *p)
{
for(; *p; p++)
{
if (!isDigit(*p) && *p != '/' && *p != '*') return 0;
}
return 1;
}Syntax
-
When you
return variables that are performing operations on the same line as the return, surround them with parenthesis.return (i+2);-
You use some magic numbers.
char in[256];I see you use the number 256 in some other places as well. Pull out that value into a
#defined variable.#define BUFLEN 256-
Use
puts() instead of printf() when you aren't formatting strings.-
Use a
default in your switch.default:
puts("Error message.");
break;Error handling:
-
It is more common to
return 0 (or some error indicator) rather than to exit(0). Both will call the registered atexit handlers and will cause program termination though. You have both spread throughout your code. Choose one to be consistent. Also, you should return different values for different errors, so you can pinpoint where something goes wrong in the future.-
Your program can't handle the input of non-whole numbers.
> 7.7*6
7, ., 7*6
7, *, 6
0
>-
Your program can't handle malformed input.
> 7a*6
7, a, *6
, *, 6
0
>-
Your program can't handle negative numbers properly
> -5+6
, -, 5+6
5, +, 6
-11
>-
Your program can't handle whitespace.
> 5 * 6
5, , *
, *,
0
>-
Your program doesn't handle no input very well.
>
,
,
0
>-
Your program can't handle numbers larger than the max size of an
int.> 99999999999999*99999999999999
9999999999999999999, *, 99999999999999
-276447231
>Code Snippets
int len(char * p) {
return int(strlen(p));
}int len(char * p)
{
return (int) strlen(p);
}int isMDGRoup(char * p) {
while(*p) {
if (!isDigit(*p) && *p != '/' && *p != '*')
return 0;
p++;
}
return 1;
}int isMDGRoup(char *p)
{
for(; *p; p++)
{
if (!isDigit(*p) && *p != '/' && *p != '*') return 0;
}
return 1;
}return (i+2);Context
StackExchange Code Review Q#42450, answer score: 12
Revisions (0)
No revisions yet.