float addition 2.5 + 2.5 = 4.0? RPN [closed] - c

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
The code below is my subprogram to do reverse polish notation calculations... basically +, -, *, and /. Everything works in the program except when I try to add 2.5 and 2.5 the program gives me 4.0... I think I have an idea why, but I'm not sure how to fix it... Right now I am reading all the numbers and operators in from command line as required by this assignment, then taking that string and using sscanf to get the numbers out of it... I am thinking that somehow the array that contains the three characters '2', '.', and '5', is not being totally converted to a float... instead i think just the '2' is. Could someone please take a look at my code and either confirm or deny this, and possibly tell me how to fix it so that i get the proper answer? Thank you in advance for any help!
float
fsm (char mystring[])
{
int i = -1, j, k = 0, state = 0;
float num1, num2, ans;
char temp[10];
c_stack top;
c_init_stack (&top);
while (1)
{
switch (state)
{
case 0:
i++;
if ((mystring[i]) == ' ')
{
state = 0;
}
else if ((isdigit (mystring[i])) || (mystring[i] == '.'))
{
state = 1;
}
else if ((mystring[i]) == '\0')
{
state = 3;
}
else
{
state = 4;
}
break;
case 1:
temp[k] = mystring[i];
k++;
i++;
if ((isdigit (mystring[i])) || (mystring[i] == '.'))
{
state = 1;
}
else
{
state = 2;
}
break;
case 2:
temp[k] = '\0';
sscanf (temp, "%f", &num1);
c_push (&top, num1);
i--;
k = 0;
state = 0;
break;
case 3:
ans = c_pop (&top);
if (c_is_empty (top))
return ans;
else
{
printf ("There are still items on the stack\n");
exit (0);
case 4:
num2 = c_pop (&top);
num1 = c_pop (&top);
if (mystring[i] == '+'){
ans = num1 + num2;
return ans;
}
else if (mystring[i] == '-'){
ans = num1 - num2;
return ans;
}
else if (mystring[i] == '*'){
ans = num1 * num2;
return ans;
}
else if (mystring[i] == '/'){
if (num2){
ans = num1 / num2;
return ans;
}
else{
printf ("Error: cannot divide by 0\n");
exit (0);
}
}
c_push (&top, ans);
state = 0;
break;
}
}
}
}
Here is my main program:
#include <stdio.h>
#include <stdlib.h>
#include "boolean.h"
#include "c_stack.h"
#include <string.h>
int main(int argc, char *argv[])
{
char mystring[100];
int i;
sscanf("", "%s", mystring);
for (i=1; i<argc; i++){
strcat(mystring, argv[i]);
strcat(mystring, " ");
}
printf("%.2f\n", fsm(mystring));
}
and here is the header file with prototypes and the definition for c_stack:
#include "boolean.h"
#ifndef CSTACK_H
#define CSTACK_H
typedef struct c_stacknode{
char data;
struct c_stacknode *next;
} *c_stack;
#endif
void c_init_stack(c_stack *);
boolean c_is_full(void);
boolean c_is_empty(c_stack);
void c_push(c_stack *,char);
char c_pop(c_stack *);
void print_c_stack(c_stack);
boolean is_open(char);
boolean is_brother(char, char);
float fsm(char[]);
in response to sixlettervariables:
Part of the assignment is to take an existing string with numbers and decimals in the array and use them to create a float which is what I am doing in these lines of code:
case 1:
temp[k] = mystring[i];
k++;
i++;
if ((isdigit (mystring[i])) || (mystring[i] == '.')) {
state = 1; } else {
state = 2;
}
break;
case 2:
temp[k] = '\0';
sscanf (temp, "%f", &num1);
c_push (&top, num1);
i--;
k = 0;
state = 0;
break;

Your stack stores char data:
typedef struct c_stacknode{
char data;
struct c_stacknode *next;
} *c_stack;
char, by definition, does not store floating point data. Instead, an integer conversion occurs when you call c_push, truncating 2.5 to 2.
You need to update your definition of struct c_stacknode, and its family of related methods, to support float data.

Could you also share the definition of c_stack? It looks like it's a stack of integer type, rounding any floating point input down. That way, 2.5 + 2.5 == 4.

if you define your variables as
int x=2.5;
and
int y=2.5;
An later you make something like
if((x+y)==4.0)
It will be true.
The engine will transform the floats numbers into integers. I guess you are doing something like this.
Look for the variables definitions.

Related

int with atoi() calculated value is always 0

I am creating a program that will calculate first degree equations. My issue is that, because an equation will include characters and operands, I need to store date on a string and then pass them to integers via atoi(). Yet, the answer value never changes from 0 (set value). Why is that?
Here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
int main()
{
char equation[10];
scanf("%s", equation);
int length = strlen(equation);
char operands[7];
int op_index[7];
int op_amount = 0;
for(int i = 0; i < length; i++){
if(equation[i] == '*' || equation[i] == '/' || equation[i] == '+' || equation[i] == '-'){
operands[op_amount] = equation[i];
op_index[op_amount] = i;
op_amount++;
}
}
char nums1[3];
char nums2[3];
int i = op_index[0] - 1;
int j = 3;
int ans = 0;
while(isdigit(equation[i]) != 0){
nums1[j] = equation[i];
j--;
i--;
}
i = op_index[0] + 1;
j = 0;
while(isdigit(equation[i]) != 0){
nums2[j] = equation[i];
j++;
i++;
}
if(operands[0] == '*'){
ans = atoi(nums1) * atoi(nums2);
}
else if(operands[0] == '/'){
ans = atoi(nums1) / atoi(nums2);
}
else if(operands[0] == '+'){
ans = atoi(nums1) + atoi(nums2);
}
else if(operands[0] == '-'){
ans = atoi(nums1) - atoi(nums2);
}
printf("ans = %d", ans);
}
You are working too hard. Or, rather you're making the computer work too hard. You don't need (or want) to "store date on a string". You do not need to copy that data around. atoi is a broken tool (undefined behavior if the input cannot be represented by an integer), but it is able to mostly do what you want. Instead of copying the data around, just pass it the first character of the string you are interested in. The following code does not handle invalid data very well (ie, the string "5 + + + 10" will be treated the same as "5 + 0" and "1foo +3x" is the same as "1+3"), but adding the logic to validate the input is left as an exercise for the reader. (hint: validating the input is a lot easier if you use strtol instead of atoi.)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int
main(int argc, char **argv)
{
char equation[1024];
int ans;
if( 1 != scanf("%1023[^\n]", equation) ){
fprintf(stderr, "No data avaialable\n");
return 1;
}
char *operator = equation + strcspn(equation, "*/+-");;
char *operand = operator + 1;
switch( *operator ){
case '*': ans = atoi(equation) * atoi(operand); break;
case '/': ans = atoi(equation) / atoi(operand); break;
case '+': ans = atoi(equation) + atoi(operand); break;
case '-': ans = atoi(equation) - atoi(operand); break;
default:
fprintf(stderr, "No operator found\n");
return 1;
}
printf("ans = %d\n", ans);
if( fflush(stdout) ){
perror("stdout");
return 1;
}
return 0;
}
Note that scanf is absolutely the wrong way to get input here, and it would make more sense to take the argument as a command line parameter. If you do read from the input stream, it would make more sense to use fgets. But I keep scanf here to demonstrate two thing: you must use a width modifier on %s and %[ conversions to prevent buffer overflow, and you should always check the return value.

Expression Tree - Operations with Characters

The user enters a string with an operation such as 4*5+2/3 and the code is supposed to make an expression tree out of it and the calculate said expression tree. I am having a problem where the program is making the expression tree with the decimal values of the ascii table instead of the actual numbers.
For example instead of 4*5+2/3, the program is storing and using 52 42 53 43 50 47 51 for the calculations. My desired run screen would be:
1 //this is the number of strings
4*5+2/3 //this is the string itself
20 //this is the result
However what I am getting is:
1 //this is the number of strings
4*5+2/3 //this is the string itself
2756 //this is the result
That is because the code is doing 52*53+50/51(because it is using the ascii values) and not 4*5+2/3.
I believe the reason for this is because I am storing 4*5+2/3 in a string of char and not in an array of int. I do not know if this is the case and would like some help.
You will not be able to run the following code as it is not complete but the whole program is five files and I do not know if I should put all of it here. I am new to both trees and StackOverflow.
This is my Make Expression Tree function and my Calculate Expression Tree function:
BTreeNode* MakeExpTree(char* exp, int len)
{
Stack stack;
BTreeNode * node, *right_node, *left_node;
InitStack(&stack);
for(int i = 0; i < len; i++){
if('0' <= exp[i] && exp[i] <= '9'){
node = CreateNode(exp[i]);
}
else{
right_node = PeekNode(&stack), Pop(&stack);
left_node = PeekNode(&stack), Pop(&stack);
node = CreateNode(exp[i]);
CreateRightSubtree(node, right_node);
CreateLeftSubtree(node, left_node);
}
PushNode(&stack, node);
}
return PeekNode(&stack);
}
int CalculateExpTree(BTreeNode* root)
{
int ret, op1, op2;
if(root == NULL){
return 0;
}
if(root->left_child == NULL && root->right_child == NULL){
return root->item;
}
op1 = CalculateExpTree(root->left_child);
op2 = CalculateExpTree(root->right_child);
switch(root->item){
case '+':
ret = op1 + op2;
break;
case '-':
ret = op1 - op2;
break;
case '*':
ret = op1 * op2;
break;
case '/':
ret = op1 / op2;
break;
case '#':
ret = op1 * pow( 2, op2);
break;
case '#':
ret = op1 / pow( 2, op2);
break;
}
return ret;
}
This is how I store the string from stdin in main function:
int main()
{
int num_exp, result, len = 0;
char input[10];
char IDK[129];
fgets(input, 9, stdin); //user enters number of strings
int m = sscanf(input, "%d", &num_exp);
char string[100][129] = { 0 };
char postfix[100][129] = { 0 };
for(int i = 0; i < num_exp; i++){
fgets(IDK, 129, stdin); //user enters string
int mm = sscanf(IDK, "%s", string[i]); //is this where the problem lies?
} //should I not be storing it in a char string?
for(int x = 0; x < num_exp; x++){
InfixToPostfix(string[x], postfix[x]); //converts strings from infix to postfix
}
BTreeNode* tree;
for(int k = 0; k < 129; k++){ //calculates length of string
if(postfix[0][k] == '\0'){
break;
}
len++;
}
tree = MakeExpTree(postfix[0], len); //makes expression tree
result = CalculateExpTree(tree); //calculates expression tree
//or is the problem in this function?
printf("%d \n", result);
return 0;
}
I am not understanding clearly what you are doing and it would help my learning too if you shared from what source are you learning these (we can chat in chat room) but I also tried to do similar thing and in my style it works partially (that is, sometimes when I insert larger number the answer is wrong but for small numbers generally correct).So you might get some help form my style of this code that calculates given string (A little help for me also would be appreciated commenters!!). 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
That is because the code is doing 52*53+50/51 (because it is using the ascii values) and not 4*5+2/3.
Yes.
I believe the reason for this is because I am storing 4*5+2/3 in a string of char and not in an array of int.
No.
In C, int is just a bigger char. There's nothing magical about them; they both hold numbers.
There are a variety of ways to derive the integer value from an ASCII character. If you have exactly one character and don't want to use a library, you can "mask off" the bits: since the ASCII range for digits is 0x30 - 0x39,
static char string[] = "4";
int value = string[0] & 0x0F;
does the trick. For more complex operations, my favorite is sscanf(3), but many use atoi(3) or various flavors of strtol(3).

How to convert a string with mathematical operators to number (integer or float)

I have a problem with converting a string like "(5+2)*3" to be able to evaluate to be 21.
Here is my code:
char inp[10];
printf("Write it: ");
scanf("%s", inp);
printf("Okay, computing!\n");
printf("INPUT: %s \n", inp);
printf("It's %d \n", (int)inp);
I would like to get a number at the end.
This code is working:
printf("19+31 is '''%d'''", 19+31);
And i need to use the second argument - the 19+31 - to be my input.
The first code outputs this:
Write it: 4+4
Okay, computing!
INPUT: 4+4
It's 329554704
You can't do this directly. C has no built-in way to evaluate expressions which are entered (as an arbitrary string) at run time. But that's exactly what you need here.
Writing an expression evaluator is a very interesting exercise -- but probably not for your first (or even second) C program.
Here is a tiny example to give you a feel for it:
#include <stdio.h>
#include <stdlib.h>
int eval(char *);
int main()
{
char expr[100];
int x;
printf("Type an expression:\n");
fgets(expr, sizeof(expr), stdin);
x = eval(expr);
printf("Answer: %d\n", x);
}
int eval(char *str)
{
char *p;
int lhs, rhs;
char op;
int r = 0;
lhs = strtol(str, &p, 10);
while(*p == ' ') p++;
op = *p++;
rhs = strtol(p, &p, 10);
switch(op) {
case '+': r = lhs + rhs; break;
case '-': r = lhs - rhs; break;
case '*': r = lhs * rhs; break;
case '/': r = lhs / rhs; break;
}
return r;
}
This works, but it's terribly limited: it handles only simple two-term expressions a+b, a-b, a*b, and a/b. (What's worse, there's no obvious way to extend it to handle fully-general expressions with parentheses and more than two terms. Handling fully-general expressions will require a completely different, more sophisticated approach.)
Addendum: Here's a -- didactically challenged -- example of that "more sophisticated approach":
#include <stdio.h>
#include <ctype.h>
int e0(char *);
int e1(char **);
int e2(char **);
int e3(char **);
void w(char **);
void q();
int main()
{
char b[100];
while(fgets(b, sizeof(b), stdin))
printf("%d\n",e0(b));
}
int e0(char *s)
{
return e1(&s);
}
int e1(char **s)
{
int r = e2(s);
while(1) {
w(s);
switch(*(*s)++) {
case '+': r += e2(s); break;
case '-': r -= e2(s); break;
default: (*s)--; return r;
}
}
}
int e2(char **s)
{
int r = e3(s);
while(1) {
w(s);
switch(*(*s)++) {
case '*': r *= e3(s); break;
case '/': r /= e3(s); break;
default: (*s)--; return r;
}
}
}
int e3(char **s)
{
int c;
w(s);
c = *(*s)++;
if(isdigit(c)) {
c -= '0';
while(isdigit(**s)) c = 10 *c + *(*s)++ - '0';
return c;
} else if(c == '-') {
return -e3(s);
} else if(c == '(') {
int r = e1(s);
w(s);
if(*(*s)++ != ')') {
q();
(*s)--;
}
return r;
} else {
q();
return 0;
}
}
void w(char **s)
{
while(**s == ' ' || **s == '\t' || **s == '\n') (*s)++;
}
void q()
{
fprintf(stderr, "?\n");
}
This works, and you're welcome to compile it and play with it. It's an unsophisticated implementation of a recursive descent parser for simple expressions involving integers, +, -, *, /, parentheses, and unary -. It can handle things like 1+2*3, (1+2)*3, and 1----2----3. (That last example is legal under this parser, though not in C.)
I called it "didactically challenged" because it's not designed for teaching -- it's a cleanup of an ill-inspired attempt I made many years ago to squeeze the code down to a bare minimum, resulting in something that was practically an IOCCC entry.

C program, Stack Calculator [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
Can someone please take a look at my code below and help me out. Ive been trying to fix this for hours but i cant figure out what's wrong. It's a program written in C that is supposed to take the operations of a stack calculator and store the operands of a mathematical expression. When an operation is performed, the last two values on the stack are removed and used as the operands, then the result of the operation is placed on the stack. However, I'm not getting the right numbers. Please take a look at my code. I know it's long, but I appreciate it. Thanks.
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#define SIZE 10
#define MAXINPUT 255
void printStack(int stack[], int tos)
{
if (isEmpty(tos))
{
printf("Stack is empty\n");
printf("---------------------------------------\n");
return;
}
printf("Stack: ");
while (tos < SIZE)
{
printf("[%d] " , stack[tos]);
tos++;
}
printf("\n---------------------------------------\n");
}
int top (int stack[], int tos)
{
if(isEmpty(tos))
return;
return stack [tos];
}
int isEmpty(int tos)
{
if (tos < 0)
return 1;
}
int isFull (int tos)
{
if(tos >= SIZE - 1)
return 1;
}
void push(int val, int stack [], int *tos)
{
if(isFull(*tos))
return;
(*tos)++;
stack[*tos] = val;
}
int pop (int stack [], int *tos)
{
if(isEmpty(*tos))
return;
int val = stack[*tos];
(*tos)--;
return val;
}
void clear(int *tos)
{
*tos = -1;
}
int getInput (char *input)
{
printf("+------------------------------{Choose an option}------------------------------+\n");
printf("| (q) : quit the program. |\n"
"| (integer value) : an integer value (either positive or negative) to push |\n"
"| (c) : clear the stack |\n"
"| (=) : display top value on the stack |\n"
"| (+) : addition |\n"
"| (-) : subtraction |\n"
"| (*) : multiplication |\n"
"| (/) : division - integer division only |\n"
"| (%) : modulus - remainder from an integer division |\n"
"| (^) : exponentiation (x raised to the power of y) |\n"
"+------------------------------------------------------------------------------+\n");
printf("Input: ");
gets(input);
if(strcmp(input, "q") == 0)
{
printf("Exiting...\n");
return 0;
}
return 1;
}
int isNum(char *input)
{
int i;
for(i = 0; i < strlen(input); i++)
{
if(!isdigit(input[i]))
return 0;
}
return 1;
}
int hasTwo(tos)
{
if((SIZE - tos) >= 2)
return 1;
printf("\nStack size is 1, must have 2 or more\n");
return 0;
}
void mathOp (char op, int stack[], int *tos)
{
if(!isEmpty(*tos))
return;
if(!hasTwo(*tos))
return;
int right = pop(stack, tos);
int left = pop(stack, tos);
switch(op)
{
case '+':
push((left + right), stack, tos);
break;
case '-':
push((left - right), stack, tos);
break;
case '*':
push((left * right), stack, tos);
break;
case '/':
push((left/right), stack, tos);
break;
case '%':
push((left % right), stack, tos);
break;
case '^':
push(pow(left, right), stack, tos);
break;
}
}
int main(int argc, char **argv)
{
int verbose = 0;
int debugMode = 0;
if (argc == 2 && argv[1][0] == '-' && argv[1][1] == 'd')
{
debugMode = 1;
if (strcmp("-dv", argv[1]) == 0)
{
verbose = 1;
}
}
int stack[SIZE];
int tos = -1;
char input[MAXINPUT];
while (getInput(input))
{
int result = 0;
if (strcmp(input, "c") == 0)
clear(&tos);
else if (strcmp(input, "=") == 0)
{
result = top(stack, tos);
printf("Top of Stack is [%d]\n", result);
}
else if (isNum(input))
push(atoi(input), stack, &tos);
else if(strcmp(input, "+") == 0 ||
strcmp(input, "-") == 0 ||
strcmp(input, "*") == 0 ||
strcmp(input, "/") == 0 ||
strcmp(input, "%") == 0 ||
strcmp(input, "^") == 0 ) mathOp(input[0], stack, &tos);
else
printf("Invalid input\n");
if (debugMode)
printStack(stack, tos);
}
return 0;
}
You have a lot of problems in this code. Compile with -Wall (or equivalent setting) to find that isEmpty and isFull and top and pop don't (always) properly return a value.
Every function that needs to return something, must end in a return statement. There is no 'default return value' of some sorts in C.
So as an example:
int isFull (int tos)
{
if(tos >= SIZE - 1)
return 1;
return 0; // <-- not full, you probably want to return 0
}
ps. You need to use %% for a literal % in the help text.
edit to fix everything:
printStack is badly broken, you need to loop from 0 to tos, not from tos to SIZE.
hasTwo needs to test if tos>=1.
mathOp needs to test first if(isEmpty(*tos)), remove the ! which says not "if not empty".
Then it should work.

Postfix evaluation using stacks and C

I was on here a while a go with a similar problem but I think with the wrong question. To give a bit of background, I a tasked with creating a C program to solve a postfix expression in the form
8 7 - 9 * =
What I think my problem is, is that my prof gave as some incorrect stack code. I say this because I am constantly getting the stack overflow (lol) error and my stack is nowhere near full. If it helps I'm using visual studio 2005. Here's my code:
#include <stdio.h>
` #include <stdlib.h>
#define STACK_SIZE 20
typedef int Bit;
Bit contents[STACK_SIZE];
int top = 0;
void make_empty(void);
int is_empty(void);
int is_full(void);
void push(Bit i);
int pop(void);
void stack_overflow(void);
void stack_underflow(void);
int main(void) {
Bit bit;
char operation;
int operand;
Bit current;
int result;
while(scanf("%d",&current)!= '=')
{
push(current);
}
scanf("%c", &operation);
while(operation != '=')
{
scanf("%d", &operand);
printf("%d\n",top);
//Pushes any number into the stack
if(operand==1||operand==2||operand==3||operand==4||operand==5||operand==6||operand==7||operand==8||operand==9||operand==0)
{
printf("entered number loop\n");
bit = operand;
if(top==20)
{
stack_overflow();
}
push(&bit);
}
//Performs subtraction operation
else if(operation == '-')
{
printf("entered minus loop\n");
if(top==1)
{
stack_underflow();
}
result = pop() - pop();
bit = result;
if(top==20)
{
stack_overflow();
}
push(&bit);
}
//Performs addition operation
else if(operation == '+')
{
if(top==1)
{
stack_underflow();
}
result = pop() + pop();
bit = result;
if(top==20)
{
stack_overflow();
}
push(&bit);
}
//Performs multiplication operation
else if(operation == '*')
{
if(top==1)
{
stack_underflow();
}
result = pop() * pop();
bit = result;
if(top==20)
{
stack_overflow();
}
push(&bit);
}
//Performs division operation
else if(operation == '/')
{
if(top==1)
{
stack_underflow();
}
result = pop() / pop();
bit = result;
if(top==20)
{
stack_overflow();
}
push(&bit);
}
else if(operation == '=')
{
if(top==0)
{
stack_underflow();
}
printf("%d\n",pop());
break;
}
}
return 0;
}
void make_empty(void) {
top = 0;
}
int is_empty(void) {
return top == 0;
}
int is_full(void) {
return top == STACK_SIZE;
}
void push(Bit i) {
if (is_full())
stack_overflow();
else
contents[top++] = i;
}
int pop(void) {
if (is_empty())
stack_underflow();
else
return contents[top--];
}
void stack_overflow(void) {
printf("Error: stack overflow!\n");
exit(EXIT_FAILURE);
}
void stack_underflow(void) {
printf("Error: stack underflow!\n");
exit(EXIT_FAILURE);
}
Now I realize that my code is a little barbaric right now and for that I apologize. That being said, any help or input at all would be greatly appreciated and thank you all in advance.
Ok, so after taking everything into account, I think I'm getting close. Everything going into the stack properly and everything is being read properly. However, my new implementation includes making everything a character and then converting the integers when they need to be used. Here is my source code once again:
#include <stdio.h>
#include <stdlib.h>
#define STACK_SIZE 20
typedef int Bit;
char contents[STACK_SIZE];
int top = 0;
void make_empty(void);
int is_empty(void);
int is_full(void);
void push(char i);
char pop(void);
void stack_overflow(void);
void stack_underflow(void);
int main(void) {
char current = 'a';
char result = 'a';
char operation = 'a';
char char1;
char char2;
int number1;
int number2;
scanf("%c", &current);
//While program successfully scanned a number
while(current != '=')
{
//Performs subtraction operation
if(current == '-')
{
printf("entered if 2\n");
char1 = pop();
number1 = char1 - '0';
printf("%d\n", number1);
char2 = pop();
number2 = char2 - '0';
printf("%d\n", number2);
result = number1 - number2;
push(result);
}
//Performs addition operation
else if(current == '+')
{
printf("entered if 2\n");
char1 = pop();
number1 = char1 - '0';
printf("%d\n", number1);
char2 = pop();
number2 = char2 - '0';
printf("%d\n", number2);
result = number1 + number2;
push(result);
}
//Performs multiplication operation
else if(current == '*')
{
printf("entered if 2\n");
char1 = pop();
number1 = char1 - '0';
printf("%d\n", number1);
char2 = pop();
number2 = char2 - '0';
printf("%d\n", number2);
result = number1 * number2;
push(result);
}
//Performs division operation
else if(current == '/')
{
printf("entered if 2\n");
char1 = pop();
number1 = char1 - '0';
printf("%d\n", number1);
char2 = pop();
number2 = char2 - '0';
printf("%d\n", number2);
result = number1 / number2;
push(result);
}
else
{
push(current);
printf("%c\n", current);
}
scanf(" %c", &current);
}
//Prints result
printf("%c\n",pop());
return 0;
}
void make_empty(void) {
top = 0;
}
int is_empty(void) {
return top == 0;
}
int is_full(void) {
return top == STACK_SIZE;
}
void push(char i) {
if (is_full())
stack_overflow();
else
contents[top++] = i;
}
char pop(void) {
if (is_empty())
stack_underflow();
else
return contents[top--];
}
void stack_overflow(void) {
printf("Error: stack overflow!\n");
exit(EXIT_FAILURE);
}
void stack_underflow(void) {
printf("Error: stack underflow!\n");
exit(EXIT_FAILURE);
}
Please keep in mind that I have been playing around with it quite a bit, so there are random printfs and useless variables all for debugging purposes. Whenever I run it (with example input 3 5 + =) I get:
So again, please excuse my some what messy code as I am quite new to C but any help would be great!
This is an endless loop:
while(scanf("%d",&current)!= '=') { push(current); }
scanf returns the number of fields read successfully. In your case this can be 0 or 1. You are comparing it to '=' which is ASCII 61. So the '"!=" is always true and you never come past this loop.
BTW, if you look at how push is implemented you see that the check for "stack overflow" is done using the is_full() function. is_full() is comparing top against STACK_SIZE. You are comparing top==20. You better should use is_full. This is more abstract and would work even if someone changed STACK_SIZE. You could even omit your checks for top==20 and top==0 because the only thing you do is call stack_underflow/stack_overflow, which is already done by the pop/push functions.
I don't see any problem with the stack. But there are at least two problems in your main.
push(&bit);
push accepts a Bit, not a Bit *. You should get a warning here, which you probably have ignored. Do not ignore the warnings.
while(scanf("%d",&current)!= '=')
This is definitely wrong. scanf retuns the number of successful input.
operand==1||operand==2||operand==3||operand==4||operand==5||operand==6||operand==7||operand==8||operand==9||operand==0
Though this is not a bug, why should you write like this? You can easily replace with:
operand >= 0 && operand <= 9
And there might be many more problems.
You have a problem with the following line:
while(scanf("%d",&current)!= '=')
The scanf function returns the number of items scanned, not the item. And scanning for %d will attempt to get an integer, not a character.
I think you should be looking more into something like:
while (scanf("%d",&current) == 1)
push(current);
which will push integers on to the stack until it can no longer scan one (i.e., you get an operation).
This is almost certainly your problem since that particular scanf will generally only return 0 or 1, meaning it will never be equal to = (which is hex 0x3d or decimal 61 if you're using ASCII). It could return EOF in some cases but that still won't give you a value of 61.
The fact that it will never return 61 means that it will simply keep looping, pushing the value of current on to your stack until it overflows, which is the behaviour you're seeing.

Resources