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
Related
I was hoping to get a bit of help, my program is supposed to take a prefix expression and generate the post fix in order. for example the expression 234*+ should generate 23+4
I am getting: Enter postfix expression: 234+
Infix expression: (3*)(2+)
I think I am on the right track just not sure what I did wrong, Thank you in advance
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define MAX_SIZE 100
typedef struct stack {
char data[MAX_SIZE];
int top;
} Stack;
void push(Stack *s, char x) {
if (s->top == MAX_SIZE - 1) {
printf("Stack overflow\n");
return;
}
s->top++;
s->data[s->top] = x;
}
char pop(Stack *s) {
if (s->top == -1) {
printf("Stack underflow\n");
return '\0';
}
char x = s->data[s->top];
s->top--;
return x;
}
int isOperator(char x) {
switch (x) {
case '+':
case '-':
case '/':
case '*':
return 1;
}
return 0;
}
int main() {
char postfix[MAX_SIZE];
char infix[MAX_SIZE];
printf("Enter postfix expression: ");
scanf("%s", postfix);
Stack s;
s.top = -1;
int i = 0;
while (postfix[i] != '\0') {
if (isOperator(postfix[i])) {
char op1 = pop(&s);
char op2 = pop(&s);
char temp[5];
temp[0] = '(';
temp[1] = op2;
temp[2] = postfix[i];
temp[3] = ')';
temp[4] = '\0';
strcat(infix, temp);
push(&s, op1);
} else {
push(&s, postfix[i]);
}
i++;
}
printf("Infix expression: %s\n", infix);
return 0;
}
I have been trying with a simple expression as stated above but not too sure what is messed up
I implemented an RPN Calculator in C. Now I want to output the current iteration meaning
Iteration 1: Contents: [5, 5]
Iteration 2: Contents: [25]
I am not quite sure how i am going to print them. I tried Printing them in the main function, but the output was coming
Iteration 1: Contents: 5
Iteration 2: Contents: 5
10
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAX_SIZE 100
int stack[MAX_SIZE];
int top = 0;
void makeEmpty()
{
top = 0;
}
bool isEmpty()
{
return top == 0;
}
bool isFull()
{
return top == MAX_SIZE;
}
void push(int value)
{
stack[top++] = value;
}
int pop()
{
if(isEmpty())
{
printf("Not enough operands in expression\n");
exit(EXIT_FAILURE);
}
return stack[--top];
}
//adds 2 integers
int add(int a, int b)
{
return a + b;
}
//subtracts 2 integers
int sub(int a, int b)
{
return a - b;
}
//multiplies 2 integers
int mul(int a, int b)
{
return a * b;
}
//divides 2 integers
int divide(int a, int b)
{
return a / b;
}
int main(void)
{
char ch;
while(1)
{
//Emptying the stack before the user enters another expression
makeEmpty();
printf("Enter an RPN expression: ");
//Reads expression from user
scanf("%c", &ch);
//parse all characters until a newline is reached
while(1)
{
if(ch == '\n')
break;
//if character is an integer
if(ch >= 48 && ch <= 57)
{
if(!isFull())
{
//convert char to int and push integer onto stack
printf("Iteration %d: Contents: %d \n", (top+1), (ch-48));
push(ch - 48);
}
else
{
//stack ran out of space, print error and exit program
printf("Expression is too complex\n");
exit(EXIT_FAILURE);
}
}
switch(ch)
{
case '+':
push(add(pop(), pop()));
break;
case '-':
push(sub(pop(), pop()));
break;
case '*':
push(mul(pop(), pop()));
break;
case '/':
push(divide(pop(), pop()));
break;
case '=':
printf("%d\n", pop());
break;
}
//get next character
scanf("%c", &ch);
}
}
return 0;
}
You can easily workaround it in your program without creating temporary stacks:
void print_stack(void)
{
printf("[");
for(int index = top -1; index >= 0; index--)
{
printf("%d%s", stack[index], index ? ", " : "");
}
printf("]\n");
}
I tried to make a calculator using stack but it works partially (that is, sometimes when I insert larger number the answer is wrong but for small numbers generally correct).I don't know may be there is some undefined behaviour in my code (and also some charachter is getting swapped somewhere see I have mentioned it in my code comment). What is wrong in it.
My code:
#include <stdio.h>
#include <string.h>
#include "stackforcalc.h"
int isOperand(char b){
if(b>='0' && b<='9'){
return 1;
}else{
return 0;
}
}
int isOperator(char b){
if(b=='+' || b=='-' || b=='*' || b=='/'){
return 1;
}
return 0;
}
int getwt(char b){
int g=-1;
switch (b)
{
case '+':
case '-':
g=1;
break;
case '/':
case '*':
g=28787868;
break;
}
return g;
}
int higherprecedence(char a,char b){
int c=getwt(a);
int d=getwt(b);
return (c>=d)?1:0;
}
int infToPost(char *b,char *str){
int j=0;
for(int i=0;i<strlen(b);i++){
if(b[i]== ' ' || b[i]== ',' ){
continue;
}
else if(isOperator(b[i])){
str[j]=' ';
j++;
while(!empty() && gettop() != '(' && higherprecedence(gettop(),b[i])){
str[j]=gettop();
j++;
pop();
}
push(b[i]);
}
else if(isOperand(b[i])){
str[j]=b[i];
j++;
}
else if(b[i]=='('){
push(b[i]);
}
else if(b[i] ==')'){
while(!empty() && gettop() != '('){
str[i]=gettop();
j++;
pop();
}
pop();
}
}
while(!empty()){
str[j]=gettop();
j++;
pop();
}
}
int Evaluate(int t,char y,int r){
int ty;
switch(y){
case '+':
ty=t+r;
break;
case '-':
ty=r-t; //I inverted these.
break;
case '*':
ty=r*t;
break;
case '/': //I inverted these because
ty=r/t; //even though I did t/r it performed r/t.
break; //may be somewhere before the numbers were swapped
default:
ty=-1;
break;
}
return ty;
}
int calculatepostfix(char *c){
for(int i=0;i<strlen(c);i++){
if(c[i]==' ' || c[i]==','){
continue;
}
else if(isOperator(c[i])){
int op1=gettop2();
pop2();
int op2=gettop2();
pop2();
int oper=Evaluate(op1,c[i],op2);
push2(oper);
}
else if(isOperand(c[i])){
int res=0;
while(i<strlen(c) && isOperand(c[i])){
res=(res*10)+(c[i]-'0');
i++;
}
i--;
push2(res);
}
}
return gettop2();
}
int main(){
char b[65];
printf("\n \n**-- Calculator --**\n");
printf("Enter expression: ");
fgets(b,sizeof(b),stdin);
char str[50];
infToPost(b,str);
int tt =calculatepostfix(str);
printf("Your answer is: %d",tt);
}
The code in "stackforcalc.h" is
#ifndef stacycalc
#define stacycalc
#define maxsize 50
char a[maxsize];
int top=-1;
int abc[maxsize];
int to=-1;
void push2(int re){ abc[++to]=re; }
void push(char b){ a[++top]=b; }
void pop2(){ to--; }
void pop(){ top--;}
int gettop2(){ return (to==-1)?-1:abc[to]; }
char gettop(){ return (top==-1)?0:a[top]; }
int empty(){ return (top==-1)?1:0; }
#endif
In infix to postfix function, in place of str[i]=gettop();, there should be
str[j]=gettop(), so the expression entered inside the brackets can be processed. Also add this piece of code after fgets to remove the '\n' that fgets may append.
fgets(b,sizeof(b),stdin);
for(int i=0;b[i]!='\0';i++){ // removes \n added by fgets
if(b[i]=='\0'){
if(b[i-1]=='\n'){
b[i-1]='\0';
}
}
}
I am creating a program that evaluates a postfix expression contained in a single line of a text file. I'm having some trouble dealing with blank spaces in the scanned file. What I've done so far is scan the single line from the file into a buffer, and then process the string one character at a time. How do I ignore blank spaces once I've read the line into a string? For example:
2 4 3 * +
Here is the full program:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
int stack[1000];
int top = -1;
void push(int x);
int pop();
bool isOperator(char ch);
int performOperation(int op1, int op2, char op);
int main()
{
char exp[1000], buffer[15];
int i, num, op1, op2, len, j, x;
int stack[1000];
char fileName[20];
FILE *inFile;
char *e;
printf("Please enter text file:");
scanf("%s", fileName);
inFile = fopen(fileName, "r");
if (inFile == NULL) {
printf("Error\n");
return -1;
}
int N = 0; i = 0, temp;
while (!feof(inFile)) {
fgets(buffer, 15, inFile);
N++;
}
printf("Postfix expression:\n");
printf("%s", buffer);
e = buffer;
while (*e != '\0') {
if (isdigit(*e)) {
num = *e - 48;
push(num);
} else {
op1 = pop();
op2 = pop();
if (isOperator(*e)) {
int ans;
ans = performOperation(op1, op2, *e);
}
push(ans);
}
e++;
}
printf(" The value of the expression is %d\n", ans);
}
void push(int x)
{
stack[++top] = x;
}
int pop()
{
return stack[top--];
}
bool isOperator(char ch) {
if (ch == '+' || ch == '-' || ch == '*'|| ch == '/')
return true;
else
return false;
}
int performOperation(int op1, int op2, char op) {
int ans;
switch (op) {
case '+':
ans = op2 + op1;
break;
case '-':
ans = op2 - op1;
break;
case '*':
ans = op2 * op1;
break;
case '/':
ans = op2 / op1;
break;
}
return ans;
}
Any help is appreciated.
I forgot to mention that we are only dealing with single-digit numbers.
You can remove the spaces so you don't have to deal with them
void remove_spaces(char* s) {
const char* d = s;
do {
while (*d == ' ') {
++d;
}
} while (*s++ = *d++);
}
If I have understood correctly the problem is processing embedded white spaces.
To resolve the problem you can rewrite the while loop at least the following way
int ans = 0;
for ( e = buffer; *e != '\0'; ++e ) {
if ( !isspace( ( unsigned char )*e ) )
{
if ( isdigit( ( unsigned char )*e ) ) {
num = *e - '0';
push(num);
} else if ( isOperator(*e) ) {
op1 = pop();
op2 = pop();
ans = performOperation(op1, op2, *e);
push(ans);
}
}
}
ans = pop();
printf(" The value of the expression is %d\n", ans);
Pay attention to this statement before the printf call
ans = pop();
You have to pop the answer from the stack before printing it. Also you should process invalid characters and check whether the stack is empty.
Also this loop
int N = 0; i = 0, temp;
while (!feof(inFile)) {
fgets(buffer, 15, inFile);
N++;
}
seams does not make sense and the condition of the loop is incorrect. For example for an empty file the variable buffer will not contain a valid data.
There are multiple problems in your code:
The loop while (!feof(inFile)) is incorrect. You should instead use:
while (fgets(buffer, sizeof buffer, inFile)) {
/* handle the string expression in buffer */
you should not push the number immediately when encountering a digit, you should parse the number that may have more than one digit.
once you parse numbers correctly, you can discard any white space encountered in the parser.
Here is a modified version:
#include <stdio.h>
bool isOperator(char ch) {
if (ch == '+' || ch == '-' || ch == '*'|| ch == '/')
return true;
else
return false;
}
int performOperation(int op1, int op2, char op) {
int ans;
switch(op) {
case '+':
ans = op2 + op1;
break;
case '-':
ans = op2 - op1;
break;
case '*':
ans = op2 * op1;
break;
case '/':
ans = op2 / op1;
break;
}
return ans;
}
int main() {
char fileName[100];
char buffer[100];
FILE *inFile;
printf("Please enter text file:");
if (scanf("%99s", fileName) != 1) {
printf("No input\n");
return 1;
}
inFile = fopen(fileName, "r");
if (inFile == NULL) {
printf("Error\n");
return -1;
}
while (fgets(buffer, sizeof buffer, inFile);
printf("Postfix expression:\n");
printf("%s", buffer);
char *e = buffer;
while (*e != '\0') {
if (isdigit((unsigned char)*e)) {
int num = 0;
while (isdigit((unsigned char)*e)) {
num = num * 10 + *e++ - '0';
}
push(num);
} else
if (isspace((unsigned char)*e) {
e++; // ignore white space
} else
if (isOperator(*e)) {
int op1 = pop();
int op2 = pop();
int ans = performOperation(op1, op2, *e++);
push(ans);
} else {
printf("Invalid character in expression: %c\n", *e++);
}
}
int ans = pop();
printf(" The value of the expression is %d\n", ans);
}
fclose(inFile);
return 0;
}
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);
}
}