Printing the wrong value when evaluating postfix expressions - c

I wrote a program which is used to evaluate postfix expression, I am not getting any compiler error/warnings but I am not getting the correct output, which probably means the issue is with the calculation but I don't know where.
My Code:
#include <ctype.h>
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define MAX 20
char s[MAX], top = 0;
void main() {
char postfix[MAX], ch;
int i, op1, op2, res;
clrscr();
printf("\n\t\t program to evaluate postfix expression");
printf("\n\t\t.......");
printf("\n enter the postfix expression:\n");
scanf("%s", &postfix);
for (i = 0; i < strlen(postfix); i++) {
ch = postfix[i];
if (isdigit(ch))
push(ch = '0');
else {
op2 = pop();
op1 = pop();
switch (ch) {
case '+':
res = op1 + op2;
break;
case '-':
res = op1 - op2;
break;
case '*':
res = op1 * op2;
break;
case '/':
res = op1 / op2;
break;
case '^':
res = pow(op1, op2);
break;
default:
printf("invalid choice");
}
push(res);
}
}
printf("result of above expression is:%d\n", pop());
getch();
}
push(int element) {
++top;
s[top] = element;
}
int pop() {
int element;
element = s[top];
--top;
return (element);
}

You should fix the typo and change push(ch = '0'); to
push(ch - '0');
ch is a character, isdigit(ch), or better isdigit((unsigned char)ch) tells you it is a digit, ch - '0'is the digit value, a number in the range0to9`.
Your code ch = '0' stores the digit '0' into ch and pushes this value, which is the character code or 0 on your system, 48 in ASCII.

Related

How to overcome the windows stopped working error message?

I'm writing a program for a simple calculator that accepts a string (without spaces) with two operators and one operand and outputs the result. My program compiles just fine but during runtime, I'm getting the windows stopped working error message. What could be the reason for it? I think it's good something to do with my program's logic. Here's my code:
#include <stdio.h>
#include <math.h>
int main()
{
int operand_1 = 0, operand_2 = 0, i = 0, result = 0;
char string[10], *ptr, operation;
ptr = string;
printf("Enter the expression:\n");
gets(string);
//puts(string);
while(*ptr==0||*ptr==1||*ptr==2||*ptr==3||*ptr==4||*ptr==5||*ptr==6||*ptr==7||*ptr==8||*ptr==9)
{
operand_1 = operand_1 + ((int)*ptr)*pow(10,i);
i++;
ptr++;
}
operation = *ptr;
ptr++;
i=0;
while(ptr!=NULL)
{
operand_2 = operand_2 + ((int)*ptr)*pow(10,i);
i++;
ptr++;
}
switch(operation)
{
case '+':
result = operand_1 + operand_2;
case '-':
result = operand_1 + operand_2;
case '*':
result = operand_1 * operand_2;
case '/':
result = operand_1 / operand_2;
case '%':
result = operand_1 % operand_2;
}
printf("%d",result);
}
I've resolved the problem and also improved the logic of the program so that it works fine.
#include <stdio.h>
#include <math.h>
int main()
{
while(1)
{
int operand_1 = 0, operand_2 = 0, i = 0, result = 0;
char string[10], *ptr, operation;
ptr = string;
printf("\nEnter the expression:");
scanf("%s",string);
if (*ptr=='q' || *ptr=='Q' && *(ptr+1)=='u' || *(ptr+1)=='U' && *(ptr+2)=='i' || *(ptr+2)=='I' && *(ptr+3)=='t' || *(ptr+3)=='T')
{
printf("\nBye");
break;
}
while(*ptr>='0' && *ptr<='9')
{
operand_1 = operand_1*10 + (*ptr - 48);
i++;
ptr++;
}
operation = *ptr;
ptr++;
i=0;
while(*ptr>='0' && *ptr<='9')
{
operand_2 = operand_2*10 + (*ptr-48);
i++;
ptr++;
}
if(operand_2 == 0)
{
printf("\nDivision by zero");
continue;
}
switch(operation)
{
case '+':
result = operand_1 + operand_2;
break;
case '-':
result = operand_1 - operand_2;
break;
case '*':
result = operand_1 * operand_2;
break;
case '/':
result = operand_1 / operand_2;
break;
case '%':
result = operand_1 % operand_2;
break;
}
printf("\nResult = %d",result);
}
}
Hope it helps someone in need :)

Unwanted symbol result when evaluating postfix expression

I'm trying to make a C program to evaluate postfix expressions and when doing so an unwanted symbol is being printed on the screen for the input 45+.
P.S. Please tell me the mistake (except of that gets() I am studying right now how to use fgets())
// to Evaluate a postfix expression
#include<stdio.h>
#include<conio.h>
int is_operator(char);
void answer();
char stack[100];
int top =-1;
void push(char);
char pop();
void main()
{
char postfix[100],item;
int i=0;
clrscr();
printf("Enter Postfix Expression");
gets(postfix);
while(postfix[i]!='\0')
{
item=postfix[i];
if(is_operator(item)==2)
{
push(item);
}
if(is_operator(item)==1)
{
char op;
int n1,n2,n3;
op=item;
n1=pop();
n2=pop();
switch(op)
{
case '+':
n3=n1+n2;
case '-':
n3=n1-n2;
case '*':
n3=n1*n2;
case '/':
n3=n1/n2;
}
push(n3);
}
i++;
}//end while
answer();
getch();
}
void push(char c)
{
top++;
stack[top]=c;
}
char pop()
{
char c;
c=stack[top];
top--;
return(c);
}
int is_operator(char i)
{
char ch=i;
if(ch=='+'||ch=='-'||ch=='*'||ch=='/')
{
return(1);
}
else
{
return(2);
}
}
void answer()
{
char ans;
ans=stack[top];
printf("Answere is %c",ans);
}
There are a lot of mistakes in your code.Try to properly type cast.
Go through comments to understand the mistakes.
Go through this for understanding character pointer and arrays.
// to Evaluate a postfix expression
#include<stdio.h>
int is_operator(char);
void answer();
int stack[100];//Use integer array since operands are integer
int top =-1;
void push(int);//Arguments changed to integer type since the stack is integer
int pop(); //Return type to integer
void main()
{
char* postfix;//Use character pointer for iterating through loop smoothly
int item;
int i=0;
printf("Enter Postfix Expression");
gets(postfix);
char c;
while(*postfix!='\0')
{
c=*postfix;
if(is_operator(c)==2)
{
push((c-'0')); //Converting char to int before pushing it into the stack
}
if(is_operator(c)==1)
{
char op;
int n1,n2,n3;
op=*postfix;
n1=pop();
n2=pop();
switch(op)
{
case '+':
n3=n1+n2;
break;
case '-':
n3=n1-n2;
break;
case '*':
n3=n1*n2;
break;
case '/':
n3=n1/n2;
break;
}
push(n3);
}
postfix++;
}//end while
answer();
}
void push(int c)
{
top++;
stack[top]=c;
}
int pop()
{
int c;
c=stack[top];
top--;
return(c);
}
int is_operator(char i)
{
char ch=i;
if(ch=='+'||ch=='-'||ch=='*'||ch=='/')
{
return(1);
}
else
{
return(2);
}
}
void answer()
{
char ans;
ans=stack[top];
printf("Answere is %d",ans);
}
I hope it is helpful....
The problems I see with your code are: your switch() is missing break statements on the individual case clauses (and a default case might be nice too); when you push your non-operators (aka single digit numbers) on the stack, you push them as character codes rather then converting them to numbers so the math doesn't make sense; you're not properly handling the order of non-communitive operations like subtraction and division (use Unix dc command as a comparison tool); finally, don't reinvent booleans. Below is a rework of your code with the above changes and some style adjustments:
// Evaluate a postfix expression
#include <ctype.h>
#include <stdio.h>
#include <stdbool.h>
char stack[100];
int top = -1;
void push(char);
char pop(void);
bool is_operator(char);
void answer(void);
void push(char c)
{
stack[++top] = c;
}
char pop()
{
return stack[top--];
}
bool is_operator(char op)
{
return (op == '+' || op == '-' || op == '*' || op == '/');
}
void answer()
{
printf("Answer is %d\n", stack[top]);
}
int main()
{
char item, postfix[100];
int i = 0;
printf("Enter Postfix Expression: ");
gets(postfix);
while ((item = postfix[i++]) != '\0')
{
if (is_operator(item))
{
char n1 = pop();
char n2 = pop();
char n3 = 0;
switch (item)
{
case '+':
n3 = n1 + n2;
break;
case '-':
n3 = n2 - n1;
break;
case '*':
n3 = n1 * n2;
break;
case '/':
n3 = n2 / n1;
break;
}
push(n3);
} else if (isdigit(item)) {
push(item - '0');
}
} // end while
answer();
return 0;
}
Example (note this evaluator only operates on single digit numbers):
> ./a.out
Enter Postfix Expression: 6 4 - 7 * 1 +
Answer is 15
> dc
6 4 - 7 * 1 + p
15

left to right evaluation

I am trying to carry out left to right evaluation in C. No order of precedence whatsoever. So 5+3*2 should be 16. I know how to do that with 2 numbers and an operator, however, I cannot figure out how to do the same thing for an expression like 2+4-5+2.
This is what I have for 2 numbers:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 20
int main(void)
{
char exp[SIZE];
int ans,c, i=0;
int length;
printf("Enter your expression: ");
fgets(exp, 20, stdin);
length = strlen(exp);
--length;
for(int j=0; j<length; j++)
{
while (exp[i]!='\n')
{
// putchar(exp[i]);
i++;
switch (exp[i])
{
case '+':
ans = (exp[i]-'0') + (exp[2]-'0');
printf("The answer is %d\n", ans);
break;
case '-':
ans = (exp[0]-'0') - (exp[2]-'0');
printf("The answer is %d\n", ans);
break;
case '*':
ans = (exp[0]-'0') * (exp[2]-'0');
printf("The answer is %d\n", ans);
break;
case '/':
ans = (exp[0]-'0') / (exp[2]-'0');
printf("The answer is %d\n", ans);
break;
default:
break;
}
}
}
exit(0);
}
Any help is appreciated.
Assuming alternating numbers and operators with single-character numbers (which seems to be what you assumed), a minimal implementation similar to your original implementation is:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 20
int main(void) {
char exp[SIZE];
int ans, length, i;
printf("Enter your expression: ");
fgets(exp, 20, stdin);
ans = exp[0] - '0';
length = strlen(exp) - 1;
for (i = 0; i < length && exp[i] != '\n'; i++) {
switch (exp[i]) {
case '+':
ans += exp[i+1] - '0';
break;
case '-':
ans -= exp[i+1] - '0';
break;
case '*':
ans *= exp[i+1] - '0';
break;
case '/':
ans /= exp[i+1] - '0';
break;
default:
break;
}
}
printf("The answer is %d\n", ans);
return 0;
}
As per your given example, assumed that each number will be single digit number.
Try this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 20
int main(void)
{
char exp[SIZE];
int ans,c, i=0;
int length,j;
printf("Enter your expression: ");
fgets(exp, 20, stdin);
length = strlen(exp);
char ch;
ans = exp[i]-'0';
i++;
while (i <= length)
{
switch (exp[i])
{
case '+':
i++;
ans += (exp[i]-'0');
break;
case '-':
i++;
ans -=(exp[i]-'0');
break;
case '*':
i++;
ans *=(exp[i]-'0');
break;
case '/':
i++;
ans /= (exp[i]-'0');
break;
default:
break;
}
i++;
//printf("The answer is %d\n", ans);
}
printf("The answer is %d\n", ans);
exit(0);
}

Calculator Program using stack

I am writing a calculator program in c using stack, In below program I used concept of infix to postfix conversion and next postfix evaluation.
I am getting correct answer for 1+2 answer is 3 but for 11+1 or any two and more digit i am getting wrong answer.
Can anyone help me what I will include in my code so that it work for more than two digit like 28+25 or any?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define SIZE 50 /* Size of Stack */
int top = -1;
char pofx[50];
char s[SIZE];
int infix_to_postfix() {
char infx[50], ch;
int i = 0, k = 0;
void push(char elem) { /* Function for PUSH operation */
s[++top] = elem;
}
char pop() { /* Function for POP operation */
return (s[top--]);
}
int pr(char elem) { /* Function for precedence */
switch (elem) {
case '#':
return 0;
case '(':
return 1;
case '+':
case '-':
return 2;
case '*':
case '/':
return 3;
}
return -1;
}
printf("\n\nEnter a Value to calculate : ");
gets(infx);
push('#');
while ((ch = infx[i++]) != '\0') {
if (ch == '(') push(ch);
else if (isalnum(ch)) pofx[k++] = ch;
else if (ch == ')') {
while (s[top] != '(')
pofx[k++] = pop();
char elem = pop(); /* Remove ( */
} else { /* Operator */
while (pr(s[top]) >= pr(ch))
pofx[k++] = pop();
push(ch);
}
}
while (s[top] != '#') /* Pop from stack till empty */
pofx[k++] = pop();
pofx[k] = '\0'; /* Make pofx as valid string */
printf("\n\nGiven Infix Expn: %s Postfix Expn: %s\n", infx, pofx);
return (int) pofx[k];
}
void postfix_evaluate() {
char ch;
int i = 0, op1, op2;
void pushit(int elem) { /* Function for PUSH operation */
s[++top] = elem;
}
int popit() { /* Function for POP operation */
return (s[top--]);
}
infix_to_postfix();
while ((ch = pofx[i++]) != '\0') {
if (isdigit(ch)) pushit(ch - '0'); /* Push the operand */
else { /* Operator,pop two operands */
op2 = popit();
op1 = popit();
switch (ch) {
case '+':
pushit(op1 + op2);
break;
case '-':
pushit(op1 - op2);
break;
case '*':
pushit(op1 * op2);
break;
case '/':
pushit(op1 / op2);
break;
}
}
}
printf("\n Given Postfix Expn: %s\n", pofx);
printf("\n Result after Evaluation: %d\n", s[top]);
}
int main() {
postfix_evaluate();
return 0;
}
part of my own code that might be useful:
if (isdigit(gi.n.nch))
{
gi.x = chr2num(gi.n.nch);
gi.n= nextchar( gi.n, len, instr);
while(isdigit(gi.n.nch))
{
gi.x *= 10;
gi.x += chr2num(gi.n.nch);
gi.n= nextchar( gi.n, len, instr);
}
}

How do I detect an operator vs. int in C using scanf?

How do I read in the following input in my RPN calculator so that it will find the operator no matter what order?
2
2+
4
As of now my scanf only sees the first char in the string and I can only do this:
2
2
+
4
I'm also trying to add an option for integer vs floating point mode. (ex. when 'i' is entered, operate in floating point and vice versa.)
#include <stdio.h>
#include <stdlib.h>
#define MAX 100
int *p;
int *tos;
int *bos;
void push(int i);
int pop(void);
int main (void)
{
int a, b;
//float c, d;
char s[80];
//char op; //declare string of 80 chars
p = (int *) malloc(MAX*sizeof(int)); //get stack memory
if (!p){
printf("Allocation Failure\n");
exit(1);
}
tos = p;
bos = p + MAX-1;
printf("\nRPN Calculator\n");
printf("Enter 'i' for integer mode\n");
printf("Enter 'f' for floating point mode\n");
printf("Enter 'q' to quit\n");
do {
printf("> ");
// gets(s);
// scanf("%s", s); //read integer
scanf("%s", s);
// switch (*s) {
switch(*s) {
case 'i':
printf("(Integer Mode)\n");
break;
case 'f':
printf("(Floating Point Mode)\n");
break;
case '+':
a = pop();
b = pop();
printf("%d\n", a+b);
push(a+b);
break;
case '-':
a = pop();
b = pop();
printf("%d\n", b-a);
push(b-a);
break;
case '*':
a = pop();
b = pop();
printf("%d\n", a*b);
push(a*b);
break;
case '/':
a = pop();
b = pop();
if(a == 0){
printf("Cannot divide by zero\n");
break;
}
printf("%d\n", b/a);
push(b/a);
break;
case '.':
a = pop();
push(a);
printf("Current value on top of stack: %d\n", a);
break;
default:
push(atoi(s));
}
} while (*s != 'q');
return 0;
}
// Put an element on the stack
void push (int i)
{
if (p > bos){
printf("Stack Full\n");
return;
}
*p = i;
p++;
}
// Get the element from the top of the stack
int pop (void)
{
p--;
if(p < 0) {
printf("Stack Underflow\n");
return 0;
}
return *p;
}
Your scanf reads the whole string. It's the following switch that judges by the first character and misses that + in 2+.
To improve it you can use the strtol function. It will parse an integer out of the string and return to you the location where the integer ended - if that's still not the end of the string, there may be an operator there.
A similar function for floating point numbers is strtod.
Here's some sample code of strtol applicable to your example:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char* input = "25+";
char* endptr;
int val = strtol(input, &endptr, 10);
if (*endptr == '\0')
{
printf("Got only the integer: %d\n", val);
}
else
{
printf("Got an integer %d\n", val);
printf("Leftover: %s\n", endptr);
}
return 0;
}
I'm not sure if I fully understood your question, but you could iterate through the string like this:
for(i = 0; i < strlen(s); i++)
{
// Here comes your switch section like this
switch(s[i]) {
.....
}
}
Remember also to include string.h.
I really didn't understand your code.
If expect the user to enter one character each time, I mean one character + enter, you should use a simple char instead of char[]. And if you pretend to use a string you should receive it and parse it pzico said.
You could do something like that. The problem would be in the treatment of numbers with multiple digits, but thinking a little bit you can fix this problem. I wrote an attempt, but I'm pretty sure it's not going to work.
printf("\nRPN Calculator\n");
printf("Enter 'i' for integer mode\n");
printf("Enter 'f' for floating point mode\n");
printf("Enter 'q' to quit\n");
scanf("%c", s);
switch(*s){
case 'i':
printf("(Integer Mode)\n");
break;
case 'f':
printf("(Floating Point Mode)\n");
break;
case 'q':
printf("Bye Bye\n");
return;
break;
}
printf("Enter the expression one character each time\n");
do {
scanf("%c", s);
switch(s) {
case '+':
a = pop();
b = pop();
printf("%d\n", a+b);
push(a+b);
break;
case '-':
a = pop();
b = pop();
printf("%d\n", b-a);
push(b-a);
break;
case '*':
a = pop();
b = pop();
printf("%d\n", a*b);
push(a*b);
break;
case '/':
a = pop();
b = pop();
if(a == 0){
printf("Cannot divide by zero\n");
break;
}
printf("%d\n", b/a);
push(b/a);
break;
case '.':
a = pop();
push(a);
printf("Current value on top of stack: %d\n", a);
break;
default:
a = pop()*10+atoi(s);
push(a);
}
} while (s != 'q');
Another problem in your code is in your pop function. What do you want to do with this test:
if(p < 0) {
printf("Stack Underflow\n");
return 0;
}
You are expecting your pointer to reach the address 0?
Anyway I hope this is not your homework.

Resources