Solved

More QUESTION for Mr.Emmons (about stack)

Posted on 1998-12-03
2
218 Views
Last Modified: 2010-04-15
We meet again! (if you're Emmons). Thanks for your answer recently about stack. For your information, I just completed the basic part of C, ie: loop, pointers, structers, switch, etc. And now I just started the data structures part which includes stack, queue, list etc. So I can't understand all the codes you wrote. Here I hope you can rewrite this program in very simplest way which I can understand and add some comments beside. I'm sure you can help !. Thanks again

*Here I enclose the question again for your reference :
    How to write a program using stack (in C language)which functions almost like a calculator. the program will receive inputs like for example : 12
    * (15 - 6) + 388  
    The program will calculate +, -, *, /, (), operations.  
    The priority operations are :

       1st. ( )
       2nd. *, /
       3rd. +, -

    The program will print the operation for example like The question above :

    15 - 6
    12 * 9
    108 + 388
    = 496






*Your answer:
                                                       Proposed Answer
    From: emmons
                                                                                  Date: Thursday, November 19 1998 - 05:15AM PST

    Some code from imladris...
    #include "stdio.h"

    #define Err(n)       printf(errm[n-1])
    #define Guard(n)     if(sp<n-1){ Err(1); break; }

    char errm[3][40] = { "Insufficient stack elements\n",
                         "Stack full\n",
                         "Invalid input\n"
                       };

    char base = 'd',buf[160];
    int cp=0;

    main()

    {       long stk[10],mem,sp;
            int i;
            char c,num[20];

            sp=-1;
            mem=0;

            do
            {       c=getnext();
                    switch(c)
                    {       case 'x':
                                    base='x';
                                    if(sp>=0)
                                    {       printf("\n");
                                            show(stk[sp]);
                                    }
                                    break;
                            case 'd':
                                    base='d';
                                    if(sp>=0)
                                    {       printf("\n");
                                            show(stk[sp]);
                                    }
                                    break;
                            case '+':
                                    Guard(2);
                                    stk[sp-1]+=stk[sp];
                                    --sp;
                                    printf("\n");
                                    show(stk[sp]);
                                    break;
                            case '-':
                                    Guard(2);
                                    stk[sp-1]-=stk[sp];
                                    --sp;
                                    printf("\n");
                                    show(stk[sp]);
                                    break;
                            case '*':
                                    Guard(2);
                                    stk[sp-1]*=stk[sp];
                                    --sp;
                                    printf("\n");
                                    show(stk[sp]);
                                    break;
                            case '/':
                                    Guard(2);
                                    stk[sp-1]/=stk[sp];
                                    --sp;
                                    printf("\n");
                                    show(stk[sp]);
                                    break;
                            case 't':
                                    printf("\n");
                                    if(sp>=0)show(stk[sp]);
                                    break;
                            case 'a':
                                    printf("\n");
                                    for(i=sp; i>=0; --i)show(stk[i]);
                                    break;
                            case 'p':
                                    Guard(1);
                                    --sp;
                                    break;
                            case 's':
                                    mem=stk[sp];
                                    break;
                            case 'r':
                                    stk[sp]=mem;
                                    break;
                            case 'm':
                                    printf("\n");
                                    show(mem);
                                    break;
                            case 'q':
                            case '\n':
                            case '\r':
                            case ' ':
                                    break;
                            default:
                                    if('0'<=c && c<='9')
                                    {       if(sp<9)
                                            {       backup();
                                                    getnum(num);
                                                    ++sp;
                                                    if(base=='d')sscanf(num,"%ld",stk+sp);
                                                    else sscanf(num,"%lx",stk+sp);
                                            }
                                            else Err(2);
                                    }
                                    else Err(3);
                    }
            } while(c!='q');
    }


    show(a)
    long a;

    {       if(base=='d')printf("%ld\n",a);
            else printf("%lx\n",a);
            return;
    }

    getnext()

    {       if(buf[cp]=='\0')getline();
            return(buf[cp++]);
    }


    backup()

    {       if(cp>0)--cp;
            return;
    }


    getnum(num)
    char *num;

    {       int dp;

            dp=0;
            while( ('0'<=buf[cp] && buf[cp]<='9') || (base=='x' && 'a'<=buf[cp] && buf[cp]<='f') )num[dp++]=buf[cp++];
            num[dp]='\0';
            return;
    }


    getline()

    {       char *sp,*dp;

            scanf("%s",buf);
            dp=buf;
            for(sp=buf; *sp!='\0'; ++sp)
            {       if(*sp!=8)*dp++=*sp;
                    else dp=dp>buf?dp-1:dp;
            }
            *dp='\0';
            cp=0;
            return;
    }
0
Comment
Question by:tagheuer
2 Comments
 
LVL 4

Accepted Solution

by:
emmons earned 50 total points
Comment Utility
Greetings again Tagheuer (I am curious that you assumed a
masculine honorific in your note.) I have commented the code
here pretty heavily. I have not changed it at all. I am not
convinced that it would be a service to change it.
The basic idea is that the user will type in a line, the program
will then parse that line onto the stack.
Try and example, or run it through the debugger. It will be far
more educational than me making the program "simpler".
If you have any specific questions, go ahead and post them and I
will do my best to answer them.
Good Luck!

#include "stdio.h"

/*
** print out the appropriate error string, based on
**      the error value returned, and an array of strings
*/

#define Err(n)       printf(errm[n-1])

/*
** check to make sure that the stack pointer has not gone
**       past the boundary. If it has, signal an error.
*/
#define Guard(n)     if(sp<n-1){ Err(1); break; }

/*
** the strings associated with user defined error conditions
*/
char errm[3][40] = { "Insufficient stack elements\n",
                     "Stack full\n",
                     "Invalid input\n"
                   };

/*
** base determines whether output is displayed in hex or decimal
**      default is decimal (base='d'.   base!='d' => hexidecimal
** buff is the buffer into which the user can write equations
*/
    char base = 'd',buf[160];

/*
** cp - character pointer, place where we are pulling information from the
**      user buffer to place onto the stack
*/
    int cp=0;

    main()

    {
            long stk[10],mem,sp;
            int i;
            char c,num[20];

            sp=-1;
            mem=0;

/*
** loop until the command that the user enters is a 'q'
*/
            do {
/*
** fetch the next character off from the stack
*/
                  c=getnext();
                  switch(c) {
                        case 'x':      /* if the command is 'x', change the display mode to hex*/
                                    base='x';
                                    if(sp>=0)
                                    {       printf("\n");
                                                show(stk[sp]);
                                    }
                                    break;
                        case 'd':      /* if the command is 'd', change the display mode decimal*/
                                    base='d';
                                    if(sp>=0)
                                    {       printf("\n");
                                                show(stk[sp]);
                                    }
                                    break;
/*
** the next four entries in the case are all the same. I have added the comments
** here, one comment for each line. To merge them into the code makes the code
** less readable to me.
*/
      /* Guard:         make sure there are two operands on the stack */
      /*                add/sub/mul/div the top entry to the entry just below it */
      /* --sp:          pop the top entry from the stack (now the sum is the top) */
      /* printf:        print a newline for the results */
      /* show(stk[sp]): display the top of the stack, the result of the add */
                        case '+':      /* if the command is '+', add the top two entries on the stack */
                                    Guard(2);
                                    stk[sp-1]+=stk[sp];
                                    --sp;                        
                                    printf("\n");            
                                    show(stk[sp]);             
                                    break;
                        case '-':
                                    Guard(2);
                                    stk[sp-1]-=stk[sp];
                                    --sp;
                                    printf("\n");
                                    show(stk[sp]);
                                    break;
                        case '*':
                                    Guard(2);
                                    stk[sp-1]*=stk[sp];
                                    --sp;
                                    printf("\n");
                                    show(stk[sp]);
                                    break;
                        case '/':
                                    Guard(2);
                                    stk[sp-1]/=stk[sp];
                                    --sp;
                                    printf("\n");
                                    show(stk[sp]);
                                    break;
                        case 't':            /* print the value that is on the top of the stack */
                                    printf("\n");
                                    if(sp>=0)show(stk[sp]);
                                    break;
                        case 'a':            /* print everything that is on the stack */
                                    printf("\n");
                                    for(i=sp; i>=0; --i)show(stk[i]);
                                    break;
                        case 'p':            /* remove the top entry from the stack (first make sure there is one) */
                                    Guard(1);
                                    --sp;
                                    break;
                        case 's':            /* store the value from the top of the stack into "memory" */
                                    mem=stk[sp];
                                    break;
                        case 'r':             /* replace the top of the stack with the value in "memory" */
                                    stk[sp]=mem;
                                    break;
                        case 'm':            /* print the value in memory */
                                    printf("\n");
                                    show(mem);
                                    break;
                        case 'q':            /* turn off the calculator (quit the program) */
                        case '\n':
                        case '\r':
                        case ' ':
                                    break;
                        default: /* if it was not an operator or a command, it must be a number */
                                     /* retrieve the number from the stack, one digit at a time */
                                     /* convert the digits into a number */
                                    if('0'<=c && c<='9') {
                                          if(sp<9) {     /* stack can only hold 9 entries */
                                                backup();   /* push this value back into the buffer */
                                                getnum(num);  /* read the next value from the buffer into "num" */
                                                ++sp;             /* push the stack down one to make room for this number */
                                                if(base=='d')
                                                      sscanf(num,"%ld",stk+sp);   /* parse the "num" string, into a number
                                                                                                   and put the number on top of the stack */
                                                else
                                                      sscanf(num,"%lx",stk+sp);
                                          } else
                                                Err(2);   /* stack is full */
                                    } else     /* invalid entry on the stack */
                                          Err(3);
                  } /* end switch case */
        } while(c!='q');
    }


/*
** display an number.
** If the "base" global is set to 'd', display the number as decimal
**    else display the number as hexidecimal
*/
    show(a)
    long a;

    {       if(base=='d')printf("%ld\n",a);
            else printf("%lx\n",a);
            return;
    }

/*
** return a line of equation from the user
** if we have finished with the current line, go get another one
*/
    getnext()

    {       if(buf[cp]=='\0')getline();
            return(buf[cp++]);
    }

/*
** the next entry in the user buffer is a number and we have already
**  grabbed one of the digits. This will move the pointer back one space
**  to allow 'getnum' to retrieve the whole number
*/
    backup()

    {       if(cp>0)--cp;
            return;
    }


/*
** get the next number off from the stack.
** The number may have hex digits if the 'base' is set to hex
** Return the number as a null terminated string in the 'num' parameter.
*/
    getnum(num)
    char *num;

    {       int dp;

            dp=0;
            while(  ('0'<=buf[cp] && buf[cp]<='9') ||
                              (base=='x' && 'a'<=buf[cp] && buf[cp]<='f') )
                        num[dp++]=buf[cp++];
            num[dp]='\0';
            return;
    }

/*
** Retrieve a line from the user.
** Parse the charaters from the line onto the stack
*/
    getline()

    {       char *sp,*dp;

            scanf("%s",buf);
            dp=buf;
            for(sp=buf; *sp!='\0'; ++sp)
            {       if(*sp!=8)*dp++=*sp;
                    else dp=dp>buf?dp-1:dp;
            }
            *dp='\0';
            cp=0;
            return;
    }  
 

0
 

Author Comment

by:tagheuer
Comment Utility
THANK YOU AGAIN ! !;
Actually before I request this question, I alredy ran this program, It works. The thing is I don't know HOW it works. But now I already understand most of the codes. And one more thing is the  program ask user to give an answer in postfix form NOT in infix form. Can you fix it (user will enter a question in infix form)?. I aspect it will be easy for you. Thank you again.



0

Featured Post

Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

Join & Write a Comment

Preface I don't like visual development tools that are supposed to write a program for me. Even if it is Xcode and I can use Interface Builder. Yes, it is a perfect tool and has helped me a lot, mainly, in the beginning, when my programs were small…
Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
The goal of this video is to provide viewers with basic examples to understand and use pointers in the C programming language.
The goal of this video is to provide viewers with basic examples to understand how to create, access, and change arrays in the C programming language.

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now