How to output elements inside of stack during RPN Calculating - c

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");
}

Related

Why is this Calculator program using stack not working? It gives some undefined behaviour ,why?

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

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

how to make getch() function takes double character instead of one?

i just want to put more than one character through the (get char) or by any other way, this is a simple calculator program using switch cases condition but cant choose a case with more than one input to the getch function for ex: 10,11....
#include <stdio.h>
#include <conio.h>
void plus_func();
void menus_func();
void mul_func();
void div_func();
void modulus_func();
void shiftleft_func();
void shiftright_func();
void and_func();
void or_func();
void not_func();
void doubleand_func();
void doubleor_func();
void notequal_func();
void xor_func();
void main(void){
int x,y, res;
int m;
int op1;
int op2;
int op3;
int i=0;
int k;
while(i==0){
printf("Enter any key to start the calculator function program or escape to exit it \n");
k=getch();
if(k!=0x1b)
{
printf("enter the first num or press escape to exit \n");
x=getch();
if(x==0x1b)
{
break;
}
else
{
op1=x-48;
}
printf("enter the second num or press escape to exit \n");
y=getch();
if(y==0x1b)
{
break;
}
else
{
op2=y-48;
}
printf("enter the type of the operation \n",m);
m=getch();
if(m==0x1b)
{
break;
}
else
{
op3=m-48;
}
switch(op3)
{
case 1: plus_func(op1,op2);break;
case 2: menus_func(op1,op2);break;
case 3: mul_func(op1,op2);break;
case 4: div_func(op1,op2);break;
case 5: modulus_func(op1,op2);break;
case 6: shiftleft_func(op1,op2);break;
case 7: shiftright_func(op1,op2);break;
case 8: and_func(op1,op2);break;
case 9: or_func(op1,op2);break;
case 10: not_func(op1,op2);break;
case 11: doubleand_func(op1,op2);break;
case 12: doubleor_func(op1,op2);break;
case 13: notequal_func(op1,op2);break;
case 14: xor_func(op1,op2);break;
default: printf("error");
break;
}
}
else
{
break;
}
}
}
void plus_func(int a, int b)
{
int c;
c=a+b;
printf("the result is %d \n",c);
}
void menus_func(int a, int b)
{
int c;
c=a-b;
printf("the result is %d \n",c);
}
void mul_func(int a, int b)
{
int c;
c=a*b;
printf("the result is %d \n",c);
}
void div_func(int a, int b)
{
int c;
c=a/b;
printf("the result is %d \n",c);
}
void modulus_func(int a, int b)
{
int c;
c=a%b;
printf("the result is %d \n",c);
}
void shiftleft_func(int a, int b){
int c;
c=a<<b;
printf("the result is %d \n",c);
}
void shiftright_func(int a, int b)
{
int c;
c=a>>b;
printf("the result is %d \n",c);
}
void and_func(int a, int b)
{
int c;
c=a&b;
printf("the result is %d \n",c);
}
void or_func(int a, int b)
{
int c;
c=a|b;
printf("the result is %d \n",c);
}
void not_func(int a, int b)
{
int c;
c=a+b;
c=~c;
printf("the result is %d \n",c);
}
void doubleand_func(int a, int b)
{
int c;
c=a&&b;
printf("the result is %d \n",c);
}
void doubleor_func(int a, int b)
{
int c;
c=a||b;
printf("the result is %d \n",c);
}
void notequal_func(int a, int b)
{
int c;
c=a+b;
c=!c;
printf("the result is %d \n",c);
}
void xor_func(int a, int b)
{
int c;
c=a^b;
printf("the result is %d \n",c);
}
This function will capture a number of digits and concatenate them into a value. To conserve space only the plus_func is include in the code and switch. The function accepts the number of digits, a sign flag and a pointer to the value. It returns an integer to indicate that ESC was pressed.
With this, each input is a fixed width. To input 3, 03 must be typed.
#include <stdio.h>
#include <conio.h>
int getint ( unsigned int digits, int sign, int *value) {
int ch = 0;
unsigned int first = digits;
*value = 0;//set to zero
while ( digits) {
while ( ( ch = getch()) < '0' || ch > '9') {
if ( ch == '-' && sign == 1 && first == digits) {// allow for negative numbers
sign = -1;
putchar ( '-');
}
if ( ch == 0x1b) {
return 1;
}
}
putchar ( ch);
*value *= 10;
*value += ch - '0';//concatenate the digits
digits--;
}
if ( sign) {
*value *= sign;
}
return 0;
}
void plus_func(int a, int b)
{
int c = 0;
c = a + b;
printf ( "\nthe result is %d\n", c);
}
int main()
{
int i = 0;
int op1 = 0;
int op2 = 0;
int op3 = 0;
unsigned int digits = 2;
do {
printf("\nenter the first %u digit num or press escape to exit \n", digits);
if ( getint ( digits, 1, &op1)) {
break;
}
printf("\nenter the second %u digit num or press escape to exit \n", digits);
if ( getint ( digits, 1, &op2)) {
break;
}
printf("\nenter the type of the operation from 01 to 14\n");
if ( getint ( digits, 0, &op3)) {
break;
}
switch ( op3) {
case 1:
plus_func ( op1, op2);
break;
default:
printf ( "error\n");
break;
}
} while ( i == 0);
return 0;
}
scanf("%d",&k);
is what you need.
More safe:
scanf_s("%d",&k);
Well, getch () cannot take more than two characters. You can use getline (), but I don't think that is what you need. You are reading numbers, not characters. So do
scanf ("%d", &k);
or use scanf_s as mentioned in #DivinCodino's answer. Also, still if you want to read characters, use getline as mentioned above or use scanf:
scanf (" %c", &k);
and declare k as
char k;
Also, your current program will not work properly as it is trying to read integers using getch, which is designed only for reading characters.
After making the changes above, the code is:
#include <stdio.h>
#include <conio.h>
void plus_func();
void menus_func();
void mul_func();
void div_func();
void modulus_func();
void shiftleft_func();
void shiftright_func();
void and_func();
void or_func();
void not_func();
void doubleand_func();
void doubleor_func();
void notequal_func();
void xor_func();
void main(void){
int x,y, res;
int m;
int op1;
int op2;
int op3;
int i=0;
int k;
while(i==0){
printf("Enter any key to start the calculator function program or escape to exit it \n");
k=getch();
if(k!=0x1b)
{
printf("enter the first num or press escape to exit \n");
scanf ("%d", &x);
if(x==0x1b)
{
break;
}
else
{
op1=x-48;
}
printf("enter the second num or press escape to exit \n");
scanf ("%d", &y);
if(y==0x1b)
{
break;
}
else
{
op2=y-48;
}
printf("enter the type of the operation \n",m);
scanf ("%d", &m);
if(m==0x1b)
{
break;
}
else
{
op3=m-48;
}
switch(op3)
{
case 1: plus_func(op1,op2);break;
case 2: menus_func(op1,op2);break;
case 3: mul_func(op1,op2);break;
case 4: div_func(op1,op2);break;
case 5: modulus_func(op1,op2);break;
case 6: shiftleft_func(op1,op2);break;
case 7: shiftright_func(op1,op2);break;
case 8: and_func(op1,op2);break;
case 9: or_func(op1,op2);break;
case 10: not_func(op1,op2);break;
case 11: doubleand_func(op1,op2);break;
case 12: doubleor_func(op1,op2);break;
case 13: notequal_func(op1,op2);break;
case 14: xor_func(op1,op2);break;
default: printf("error");
break;
}
}
else
{
break;
}
}
}
void plus_func(int a, int b)
{
int c;
c=a+b;
printf("the result is %d \n",c);
}
void menus_func(int a, int b)
{
int c;
c=a-b;
printf("the result is %d \n",c);
}
void mul_func(int a, int b)
{
int c;
c=a*b;
printf("the result is %d \n",c);
}
void div_func(int a, int b)
{
int c;
c=a/b;
printf("the result is %d \n",c);
}
void modulus_func(int a, int b)
{
int c;
c=a%b;
printf("the result is %d \n",c);
}
void shiftleft_func(int a, int b){
int c;
c=a<<b;
printf("the result is %d \n",c);
}
void shiftright_func(int a, int b)
{
int c;
c=a>>b;
printf("the result is %d \n",c);
}
void and_func(int a, int b)
{
int c;
c=a&b;
printf("the result is %d \n",c);
}
void or_func(int a, int b)
{
int c;
c=a|b;
printf("the result is %d \n",c);
}
void not_func(int a, int b)
{
int c;
c=a+b;
c=~c;
printf("the result is %d \n",c);
}
void doubleand_func(int a, int b)
{
int c;
c=a&&b;
printf("the result is %d \n",c);
}
void doubleor_func(int a, int b)
{
int c;
c=a||b;
printf("the result is %d \n",c);
}
void notequal_func(int a, int b)
{
int c;
c=a+b;
c=!c;
printf("the result is %d \n",c);
}
void xor_func(int a, int b)
{
int c;
c=a^b;
printf("the result is %d \n",c);
}
This code still does not work, but I haven't done any changes except changing getch to scanf.

What is wrong with my program implementing a stack in C

Hi i have a problem with my stack data structure program. It seems that when i define the size of my array/the imaginary size of array just to call it through a loop the size i defined or specified by the user is being depleted or somewhat edited when i enter a data or push.
For ex. i entered 5 for the size and choose push and then add 2. It is working properly. But if i choose to push data again, it is now passing to the size variable. I do not know understand what is happening...
#include <stdio.h>
#include <ctype.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>
#define p printf
#define s scanf
int top;
int ar[1];
int size;
main()
{
void push();
int opt, num;
char cont[] = { 'y' };
clrscr();
p("Stacking Program");
p("\n\nData Size: ");
s("%d", &size);
p("\n");
while((cont[0] == 'y') || (cont[0] == 'Y'))
{
clrscr();
p("Stacking Program");
p("\n\nData Size: %d\n\n", size);
p("MAIN MENU\n1. Pop\n2. Push\n3. Pick\n4. View\nChoose: ");
s("%d", &opt);
p("\n");
switch(opt) {
case 1:
pop();
break;
case 2:
if(top > size)
{
p("You can't push more data");
}
else
{
p("Enter data for Data[%d]: ", top);
s("%d", &num);
push(num);
}
break;
case 3:
pick();
break;
case 4:
view();
break;
default:
p("Your choice is not in the list.");
break;
}
p("\n\nDo you want continue\(Y\/N\)?");
s("%s", &cont[0]);
}
}
pop()
{
int a;
if(top < 0)
{
p("Stack empty.");
return 0;
}
else
{
a = ar[top];
p("\(Data[%d] = %d\) removed.", top, a);
top--;
}
}
void push(int b)
{
top++;
ar[top] = b;
}
pick()
{
if(top < 0)
{
p("Nothing to display.");
return 0;
}
else
{
p("\(Data[%d] = %d\) is the last data.", top, ar[top]);
}
}
view()
{
int i;
if(top < 0)
{
p("Nothing to display.");
return 0;
}
else
{
for(i = 1; i < (top + 1); i++)
{
p("Data[%d] = %d\n", i, ar[i]);
}
}
}
You need to define the size of the array at runtime, using the size entered by the user.
instead of:
int top;
int ar[1];
int size;
...
int top = -1;
int *ar = NULL;
int size = 0;
and then after getting size from the user:
if ( size > 0 )
{
ar = malloc(size * sizeof(int));
if ( ar == NULL )
{
printf("ERROR: malloc() failed\n");
exit(2);
}
}
else
{
printf("ERROR: size should be positive integer\n");
exit(1);
}
....
p("\n\nDo you want continue(Y/N)?");
s("%s", &cont[0]);
}
free(ar);
} // end of main
I think the for loop in view() should be:
for(i = 0 ; i <= top ; i++)
also
case 2:
if ( top == ( size - 1 ))
If you don't want to dynamically size the array, another approach is to allocate an array with MAXSIZE elements, where MAXSIZE is "big enough". Also, some other comments:
You declared at the top of your program a character array of size 1:
char cont[] = { 'y' };
But in your scanf line later you try to use this:
s("%s", &cont[0]);
This will overflow your buffer even if the user types just one character, because %s assumes that the buffer has at least two bytes available, one for the character and one for the '\0'. Possible fix:
char cont[] = { 'y', '\0' };
// ...
s("%1s", cont);
Note that cont is the same and more common way of saying &cont[0].
Another problem is with things that might be caught by the compiler if warnings are turned on: all functions should be prototyped before they are mentioned, functions without explicit return type should be declared with type int, and you should not let a function drop off without returning a value even though you declared it to explicitly or implicitly. Also, '(' and ')' do not need to be escaped in string literals.
Here is a modified version with changes noted. I have redefined clrscr() because I don't have conio.h on this system:
#include <stdio.h>
#include <ctype.h>
// #include <conio.h>
#define clrscr() printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n")
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#define p printf
#define s scanf
#define MAXSIZE 500
// prototypes [Changed]
int pop();
void push(int b);
int pick();
int view();
int top;
int ar[MAXSIZE];
int size;
int main()
{
int opt, num;
char cont[] = { 'y', '\0' }; // [Changed]
clrscr();
p("Stacking Program\n\n");
// keep asking until we get a valid size [Changed]
for (;;)
{
p("Data Size: ");
s("%d", &size);
if (size > 0 && size < MAXSIZE)
break;
printf("Not a valid size!\n");
}
p("\n");
while((cont[0] == 'y') || (cont[0] == 'Y'))
{
clrscr();
p("Stacking Program");
p("\n\nData Size: %d\n\n", size);
p("MAIN MENU\n1. Pop\n2. Push\n3. Pick\n4. View\nChoose: ");
s("%d", &opt);
p("\n");
switch(opt) {
case 1:
pop();
break;
case 2:
if(top > size)
{
p("You can't push more data");
}
else
{
p("Enter data for Data[%d]: ", top);
s("%d", &num);
push(num);
}
break;
case 3:
pick();
break;
case 4:
view();
break;
default:
p("Your choice is not in the list.");
break;
}
p("\n\nDo you want continue(Y/N)?");
s("%1s", cont); // [Changed]
}
return 0;
}
int pop()
{
int a;
if(top == 0) // [Changed]
{
p("Stack empty.");
return 0;
}
else
{
top--; // [Changed]
a = ar[top];
p("(Data[%d] = %d) removed.", top, a);
return a; // [Changed]
}
}
void push(int b)
{
ar[top] = b;
top++; // [Changed]
}
int pick()
{
if(top == 0) // [Changed]
{
p("Nothing to display.");
return 0;
}
else
{
p("(Data[%d] = %d) is the last data.", top, ar[top-1]); // [Changed]
return -1; // [Changed]
}
}
int view()
{
int i;
if(top < 0)
{
p("Nothing to display.");
return 0;
}
else
{
for(i = 0; i < top; i++) // [Changed]
{
p("Data[%d] = %d\n", i, ar[i]);
}
return -1; // [Changed]
}
}

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