Skip to content

Commit 35c2e39

Browse files
committed
Initial commit
Completed exercise.
1 parent 400282b commit 35c2e39

File tree

1 file changed

+114
-0
lines changed

1 file changed

+114
-0
lines changed

chapter07/7-5.c

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/*
2+
* Exercise 7-5. Rewrite the postfix calculator of Chapter 4 to use scanf
3+
* and/or sscanf to do the input and number conversion.
4+
*
5+
* Note: Rewrote getop to use getchar and ungetc to peak at the next character
6+
* before calling scanf to handle the input and number conversion. getop takes
7+
* a double as an argument.
8+
*
9+
* Faisal Saadatmand
10+
*/
11+
12+
#include <stdio.h>
13+
#include <stdlib.h>
14+
#include <ctype.h>
15+
16+
#define MAXOP 100 /* max size of operand or operator */
17+
#define NUMBER '0' /* signal that a number was found */
18+
#define MAXVAL 100 /* maximum depth of val stack */
19+
#define BUFSIZE 100
20+
21+
/* functions */
22+
void push(double);
23+
double pop(void);
24+
int getop(double *);
25+
26+
/* globals */
27+
int sp = 0; /* next free stack position */
28+
double val[MAXVAL]; /* value stack */
29+
30+
/* push: push f onto value stack */
31+
void push(double f)
32+
{
33+
if (sp < MAXVAL)
34+
val[sp++] = f;
35+
else
36+
printf("error: stack full, can't push %g\n", f);
37+
}
38+
39+
/* pop: pop and return top value from stack */
40+
double pop(void)
41+
{
42+
if (sp > 0)
43+
return val[--sp];
44+
else {
45+
printf("error: stack empty\n");
46+
return 0.0;
47+
}
48+
}
49+
50+
/* getop: get next operator or numeric operand - scanf version */
51+
int getop(double *number)
52+
{
53+
char c, sign;
54+
55+
sign = 0;
56+
while (isblank(c = getchar())) /* skip blank characters */
57+
;
58+
59+
if (c == '+' || c == '-') { /* check for sign */
60+
sign = c;
61+
if (!isdigit(c = getchar()) && c != '.') { /* take a peak */
62+
ungetc(c, stdin); /* not a sign (possible operator) */
63+
return sign;
64+
}
65+
}
66+
67+
if (isdigit(c) || c == '.') { /* take a peak */
68+
ungetc(c, stdin); /* push c back onto input stream */
69+
if (sign > 0)
70+
ungetc(sign, stdin);
71+
if (scanf("%lf", number) == 1) /* scan and convert numbers */
72+
return NUMBER;
73+
}
74+
return c;
75+
}
76+
77+
/* reverse polish calculator - scanf/sscanf version */
78+
int main(void)
79+
{
80+
int type;
81+
double op2, op;
82+
83+
while ((type = getop(&op)) != EOF) {
84+
switch (type) {
85+
case (NUMBER):
86+
push(op);
87+
break;
88+
case '+':
89+
push(pop() + pop());
90+
break;
91+
case '*':
92+
push(pop() * pop());
93+
break;
94+
case '-':
95+
op2 = pop();
96+
push(pop() - op2);
97+
break;
98+
case '/':
99+
op2 = pop();
100+
if (op2 != 0.0)
101+
push(pop() / op2);
102+
else
103+
printf("error: zero division\n");
104+
break;
105+
case '\n':
106+
printf("\t%.8g\n", pop());
107+
break;
108+
default:
109+
printf("error: unknown command %c\n", type);
110+
break;
111+
}
112+
}
113+
return 0;
114+
}

0 commit comments

Comments
 (0)