Hello here in k&r excerise of primitive calculator i get it and all but there something i think its weird and i don't somewhat get it here the getch and ungetch functions i don't get it's routine

#include <stdio.h>
#include <stdlib.h> /* for atof() */
#include <ctype.h>
#define MAXOP 100 /* max size of operand or operator */
#define NUMBER '0' /* signal that a number was found */
#define MAXVAL 100 /* maximum depth of val stack */
#define BUFSIZE 100
int sp = 0; /* next free stack position */
double val[MAXVAL]; /* value stack */
int getop(char []);
void push(double);
double pop(void);
/* reverse Polish calculator */
int main(void)
{
    int type;
    double op2;
    char s[MAXOP];
    while ((type = getop(s)) != EOF) {
        switch (type) {
            case NUMBER:
                push(atof(s));
                break;
            case '+':
                push(pop() + pop());
                break;
            case '*':
                push(pop() * pop());
                break;
            case '-':
                op2 = pop();
                push(pop() - op2);
                break;
            case '/':
                op2 = pop();
                if (op2 != 0.0)
                    push(pop() / op2);
                else
                    printf("error: zero divisor\n");
                    break;
            case '\n':
                printf("\t%.8g\n", pop());
                break;
            default:
                printf("error: unknown command %s\n", s);
                break;
        }
    }
    return 0;
}
/* push: push f onto value stack */
void push(double f)
{
    if (sp < MAXVAL)
        val[sp++] = f;

    else
        printf("error: stack full, can't push %g\n", f);
}
/* pop: pop and return top value from stack */
double pop(void) {
    
    if (sp > 0)
        return val[--sp];
    else {
        printf("error: stack empty\n");
        return 0.0;
    }
}

int getch(void);
void ungetch(int);
/* getop: get next character or numeric operand */
int getop(char s[])
{
    int i, c;
    while ( (s[0] = c = getch() ) == ' ' || c == '\t');
        s[1] = '\0';
    if (!isdigit(c) && c != '.') 
        return c; /* not a number */
    i = 0;
    if (isdigit(c)) /* collect integer part */
        while (isdigit(s[++i] = c = getch())) ;
    if (c == '.') /* collect fraction part */
        while (isdigit(s[++i] = c = getch()));
    s[i] = '\0';
    if (c != EOF)
        ungetch(c);
    return NUMBER;
}


char buf[BUFSIZE]; /* buffer for ungetch */
int bufp = 0; /* next free position in buf */
int getch(void) {/* get a (possibly pushed-back) character */
    return (bufp > 0) ? buf[--bufp] : getchar() ;
}
void ungetch(int c) /* push character back on input */
{
    bufp >= BUFSIZE ? printf("ungetch: too many characters\n") : buf[bufp++] = c ;
}

here first time let's say we read first time it will decerment buffp to -1 which will get undefined result how does all all come together then and in ungetch which suppose to push back character on input all it's doing is just copying the character i don't see any deletion here ! .... I hope someone clarify this for me

Recommended Answers

All 7 Replies

nvm about buff deceremting part it won't decerement it only after 2nd time i think but how does ungetch deletes input ?

when you 'getch' you're taking the next character off of the input queue for processing.

this assumes once you've processed it, you're done with it, and will (probably) eventually want to get another character off the input queue.

'ungetch' puts that input back on the input queue.

this effectively allows you to "peek" at the input queue and know what the next character is without destroying it, so that it can be used again at some other point.

okay thanks i get it but there isn't the order of evulatution for
while (isdigit(s[++i] = c = getch())) ; is right to left ?
like for example after we enter at test if(c=='.') shouldnt it quit coz
isdigit(s[++i] contains nothing or coz i m doing it inside the function i m assigning that ++i to the character that will get read ?

okay i understood it but i got other problem now its not acctually a problem but the exerise to add - i got it to work aswell but when i added couple of printf it didn't work this is weird

#include <stdio.h>
#include <stdlib.h> /* for atof() */
#include <ctype.h>
#include <math.h>
#define MAXOP 100 /* max size of operand or operator */
#define NUMBER '0' /* signal that a number was found */
#define MAXVAL 100 /* maximum depth of val stack */
#define BUFSIZE 100
int sp = 0; /* next free stack position */
double val[MAXVAL]; /* value stack */
int getop(char []);
void push(double);
double pop(void);
/* reverse Polish calculator */
int main(void)
{
    int type;
    int i=0,count=0;
    double op2;
    char s[MAXOP];
    while ((type = getop(s)) != EOF) {
        switch (type) {
            case NUMBER:
                push(atof(s));
                break;
            case '+':
                push(pop() + pop());
                break;
            case '*':
                push( pop() * pop() );
                break;
            case '-':
                op2 = pop();
                push(pop() - op2);
                break;
            case '/':
                op2 = pop();
                if (op2 != 0.0)
                    push(fmod(pop(),op2));
                else
                    printf("error: zero divisor\n");
                    break;
            case '%':
                op2 = pop();
                    if(op2!=0)
                        fmod(pop(), op2);
            case '\n':
                printf("\tanswer is%.8g\n", pop());
                break;
            default:
                printf("error: unknown command %s\n", s);
                break;
        }
    }
    return 0;
}
/* push: push f onto value stack */
void push(double f)
{

    if (sp < MAXVAL) {
        val[sp++] = f;
        printf("val[sp]=%g",val[sp]);//we gonna use for verifacation
        getchar();
    }
    else
        printf("error: stack full, can't push %g\n", f);
}
/* pop: pop and return top value from stack */
double pop(void) {

    if (sp > 0)
        return val[--sp];
    else {
        printf("error: stack empty\n");
        return 0.0;
    }
}

int getch(void);
void ungetch(int);
/* getop: get next character or numeric operand */
int getop(char s[])
{
    int i, c,next;
    while ( (s[0] = c = getch() ) == ' ' || c == '\t');
        s[1] = '\0';
    if (!isdigit(c) && c != '.' && c!='-')
        return c; /* not a number */
    i = 0;
    if(c=='-') {
        //save the variable after it
        next=getch();//get next character
        if(isspace(next))//then its operand
            return c;
        //we didnt do else coz it will be the same since return will return from the whole function
        s[i]=c;//reassign c to negative
        c=next;//assign c to next which is a number after the -
        s[++i]=c;//now assign next character in the array now to the number
    }
    if (isdigit(c)) { /* collect integer part */
        while (isdigit(s[++i] = c = getch()));
    }
    if (c == '.') /* collect fraction part */
        while (isdigit(s[++i] = c = getch()));
    s[i] = '\0';
    if (c != EOF)
        ungetch(c);
    return NUMBER;
}


char buf[BUFSIZE]; /* buffer for ungetch */
int bufp = 0; /* next free position in buf */
int getch(void) {/* get a (possibly pushed-back) character */
    return (bufp > 0) ? buf[--bufp] : getchar() ;
}
void ungetch(int c) /* push character back on input */
{
    bufp >= BUFSIZE ? printf("ungetch: too many characters\n") : buf[bufp++] = c ;
}

line 63 and 64 when i removed the printf debug there there was no problem is somehow printf altered the memory of val double? or what

you need to post a question if you want an answer.

i fixed problem was that i incremented sp then used it in printf which made it next time i used the value i used the incremented one which contained rubbish value

anyways thanks for clarifying the function for me

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.