#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2012
    Posts
    11
    Rep Power
    0

    Reverse polish calculator and reading from file


    I have a question about reverse polish calculator, here is the K&R reverse polish calculator. I had the calculator working but now I need it to take information from a file. Here is a quick sample of the input file.
    #First example from the textbook
    1 2 - 4 5 + *
    #Compute 5!
    1 2 3 4 5 ****
    #Here come binomial(14, 9) and binomial(14, 5)
    1 = 6 * 1 / = 7 * 2 / = 8 * 3 / = 9 * 4 / = 10 * 5 / = 11 * 6 / = 12 * 7 / = 13 * 8 / = 14 * 9 /
    1 = 10 * 1 / = 11 * 2 / = 12 * 3 / = 13 * 4 / = 14 * 5 /

    My code is below I have readLine which takes a # statement and just prints it since it is a comment. I was going to have my RPN function call the readLine function until EOF and fprintf it into a file and just loop like that but I am having problem implementing it. Can anyone give me some advice? And explain how exactly RPN, getop exactly work. Thanks.
    Code:
    //
    //  main.c
    //  inputReader
    //
    
    #include <stdio.h>
    #include <ctype.h>
    #include <stdio.h>
    #include <stdlib.h>
    #define NUMBER '0'
    #define MAXOP 100
    #define MAXVAL 100
    #define BUFSIZE 100
    int sp = 0;
    char out[256];
    double val[MAXVAL];  /* value stack */
    int buff[1024];
    int i;
    int run;
    double pop(void);
    void push(double f);
    int getch(void);
    void ungetch(int c);
    char *RPNCalc()
    {
    	int type, iop2;
    	double op1, op2, store_val;
    	char s[MAXOP];
    	char *outp = out;
    	while ((type = getop(s)) != EOF) {
    		switch (type) {
                case NUMBER:
                    push(atof(s));
                    break;
                case 'x':		//exchange top two stack items
                    op1 = pop();
                    op2 = pop();
                    push(op1);
                    push(op2);
                    break;
                case 'R':
                    push(store_val);
                    break;
                case 'S':
                    store_val = pop();
                    break;
                case 0xd:		//skip cr
                    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
                        outp += sprintf(outp, "error: zero divisor\n");
                    break;
                case '=':	
                    outp += sprintf(outp, "\t%.16g\n", op2 = pop());
                    push(op2);
                    break;
                case '\n':
                    outp += sprintf(outp, "\t%.16g\n", op2 = pop());
                    push(op2);
                    return out;
                    break;
                default:
                    outp += sprintf(outp, "error: unknown command %s\n", s);
                    break;
    		}
    	}
    	return out;
    }
    
    int getop(char s[])
    {
        int i, c;
        while ((s[0] = c = getch()) == ' ' || c == '\t')
            ;
        s[1] = '\0';
        if (!isdigit(c) && c != '.')
            return c;
        i = 0;
        if (isdigit(c))
            while (isdigit(s[++i] = c = getch()))
                ;
        if (c == '.')
            while (isdigit(s[++i] = c = getch())); s[i] = '\0';
        if (c != EOF)
            ungetch(c);
        return NUMBER;
    }
    char buf[BUFSIZE];
    int bufp = 0;
    int getch(void)
    {
        return (bufp > 0) ? buf[--bufp] : getchar();
    }
    void ungetch(int c)
    {
        if (bufp >= BUFSIZE)
            printf("ungetch: too many characters\n");
        else
            buf[bufp++] = c;
    }
    void push(double f)
    {
        if (sp < MAXVAL)
            val[sp++] = f;
        else
            printf("error: stack full, can't push %g\n", f);
    }
    double pop(void)
    {
        if (sp > 0)
            return val[--sp];
        else {
            printf("error: stack empty\n");
            return 0.0;
        }
    }
    int readLine(FILE *fp)
    {
        i = 0;
        char c;
        while( (c = fgetc(fp)) != EOF && (c ) != '\n')
        {
            if ( c == '#' )
            {
                printf("%c", c);
                while( (c = fgetc(fp)) != EOF && c != '\n')
                {
                    printf("%c", c);
                }
                printf("\n");
                return 0;
            }
            buff[i] = c;
            i++;
            run = 1;
            printf("%c", c);
        }
        printf("\n");
        return 0;
    }
    int main(int argc, const char * argv[])
    {
    
        FILE *fp;
        if ((fp = fopen ("/Documents/buffthat/buffthat/input.txt", "rb")) == NULL)
            return -1;
        readLine(fp);
        readLine(fp);
        readLine(fp);
        return 0;
    }
  2. #2
  3. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,145
    Rep Power
    2222
    Yes, my first piece of advice for you is that you use code tags! Only then might we have some semblence of a chance of deciphering the code. As it is now, it's a huge unreadable mess.
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2012
    Posts
    11
    Rep Power
    0

    Apologies


    I am sorry, new to posting on this forum, was not sure on how to do it. Should of looked more into before posting. I am sorry for that.
  6. #4
  7. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,145
    Rep Power
    2222
    Using blank lines to separate functions from each other, globals from functions, and variable declarations from code would also help. But the most essential is the code tags.

    readLine reads a line from the file and puts it into buf.
    RPNCalc reads from buf and outputs to out.

    So then after a call to readLine, call RPNCalc and read the output from out.
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2012
    Posts
    11
    Rep Power
    0

    Question


    Thank you for the advice, I had a follow up question. First would I just pass the buffer that I made over to rpncalc? Second should that buffer be an buffer of integers or characters? Also how would I change the while loop in RPNCalc to work with my readline? Should I have readLine return 1 for true if it read a line and 2 for if there is no more lines? Or do you have another suggestion on how to handle that. Sorry, I have a strong JAVA back ground but trying to jump into c and learn it.
  10. #6
  11. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2012
    Posts
    11
    Rep Power
    0

    Help


    Here what I modded to try and get input into rpn calculator. This does the job of reading the buffer backwards from getChar after using readLine. I tried it with a data line but it ran into some major errors. Was wondering if someone could explain to me the getop method in there. Thanks, and what I am doing wrong too please.

    Code:
    int readLine(FILE *fp)
    {
        readVal = 0;
        i = 0;
        char c;
        while( (c = fgetc(fp)) != EOF && (c ) != '\n')
        {
            if ( c == '#' )
            {
                printf("%c", c);
                while( (c = fgetc(fp)) != EOF && c != '\n')
                {
                    printf("%c", c);
                }
                printf("\n");
                return readVal;
            }
            readVal = 1;
            buff[i] = c;
            i++;
            run = 1;
            printf("%c", c);
        }
        printf("\n");
        return readVal;
    }
    int getChar(void)
    {
        char b;
        if ( i > 0)
        {
            b = buff[--i];
        }
        return b;
    }
    int getop(char s[], FILE *fp)
    {
        int i, c;
        while ((s[0] = c = getChar() ) == ' ' || c == '\t')
            ;
        s[1] = '\0';
        if (!isdigit(c) && c != '.')
            return c;
        i = 0;
        if (isdigit(c))
            while (isdigit(s[++i] = c = getChar()))
                ;
        if (c == '.')
            while (isdigit(s[++i] = c = getChar())); s[i] = '\0';
        if (c != EOF)
            ungetch(c);
        return NUMBER;
    }

IMN logo majestic logo threadwatch logo seochat tools logo