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
//

#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;
}
}
{
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;
return 0;
}```
2. 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.
3. 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.
4. 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.
5. 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.
6. 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)
{
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");
}
buff[i] = c;
i++;
run = 1;
printf("%c", c);
}
printf("\n");
}
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;
}```