Page 159

Rewrite the postfix calculator of Chapter 4 to use scanf and/or sscanf to do the input and number conversion.

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define LOWVAR 'a'
#define HIGHVAR 'z'
#define MAXOP 100
#define NUMBER '0'

int getterm(char[]);
void push(double);
double pop(void);
double read(void);
void clear(void);
void assign(char, double);
double fetch(char);

int main()
{
	int type;
	double op, op2;
	char s[MAXOP];

	while (getterm(s) != EOF) {
		if (s[0] == '\n') {
			printf("\t%.8g\n", pop());
		} else if (sscanf(s, "%lg", &op)) {
			push(op);
		} else if (sscanf(s, "%c", s)) {
			switch (s[0]) {
			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 '%':
				op2 = pop();
				if (op2 != 0.0) {
					push((int)pop() % (int)op2);
				} else {
					printf("error: zero divisor\n");
				}
				break;
			case '#': // print top element
				printf("\t%.8g\n", read());
				break;
			case '&': // duplicate top element
				push(read());
				break;
			case '~': // swap top two elements
				op = pop();
				op2 = pop();
				push(op);
				push(op2);
				break;
			case '!': // clear the stack
				clear();
				break;
			case '$':
				push(sin(pop()));
				break;
			case '?':
				push(exp(pop()));
				break;
			case '^':
				op2 = pop();
				push(pow(op2, pop()));
				break;
			case '\n':
				break;
			}
		}
	}

	return 0;
}

#include <ctype.h>

int getch(void);
void ungetch(int);
int getterm(char out[])
{
	char *p = out;

	while (isspace(*p = getch()) && *p != '\n')
		;

	if (*p == EOF || *p == '\n') {
		return *p;
	}

	while (!isspace(*++p = getch()))
		;

	ungetch(*p);

	*p = '\0';
	return out[0];
}

#define MAXVAL 100

int sp = 0;
double val[MAXVAL];

void push(double f)
{
	if (sp < MAXVAL) {
		val[sp++] = f;
	} else {
		printf("push error: stack full, can't push %g\n", f);
	}
}

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

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

void clear(void)
{
	sp = 0;
}

#define BUFSIZE 100
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;
	}
}

double vars[HIGHVAR - LOWVAR];

void assign(char c, double d)
{
	vars[c - LOWVAR] = d;
}

double fetch(char c)
{
	return vars[c - LOWVAR];
}