Ron Ford <
[email protected]> writes:
[reordered and snipped]
#include <stdio.h>
#define NUMBER '0'
int getop(double *val);
double push(double val);
double pop(void);
void clear(void);
int main(void)
{
int op;
double num;
while ((op = getop(&num)) != EOF) {
switch (op) {
case NUMBER:
push(num);
break;
case '+':
push(pop() + pop());
break;
case '*':
push(pop() * pop());
break;
case '-':
num = pop();
push(pop() - num);
break;
case '/':
num = pop();
if (num)
push(pop() / num);
else fprintf(stderr, "Error: division by zero.");
break;
case '#':
push(push(pop()));
break;
case 'c':
clear();
break;
case '=':
printf("\t%g\n", push(pop()));
break;
default:
fprintf(stderr, "Error: unknown operation %c.\n", op);
break;
}
}
return 0;
}
Alright, Ben, I'm back in the saddle and have some time to put toward a
solution here. What you have above is close to every solution I've seen
for this calculator with a couple exceptions. One is that you don't have a
case for '!', but that's no big deal, we can add it. The other is that
you have a differing type for the argument of getop. That's a significant
change.
This little program is getting to be 200 lines, so if we can figure out the
switch control part of it, then we can omit almost all of it until we think
we have a final solution, which would be a good thing. We could simply
leave the case for say '%', to be able to have something that any clc'er
can compile and check behavior for.
Now that I've had a few days to think about it, I would actually like to
end up with a calculator I can use. The feature that I don't think we've
coded for that has reference to the above is how better to manipulate the
stack. My HP something C had a rotate feature that, along with other
operations, allowed me to get whatever stack values I wanted in the first
and second positions. So it is that I would have a relevant value on the
stack, and usually the final calculation would be to rotate the stack, and
what was on the top would be on the bottom, and magically, the other
relevant value was in the second position, ready for the final divide that
would be the answer.
So, I think we need a rotate that does
4
3
2
1
=>
3
2
1
4
and a swap that does
3
2
1
4
=>
3
2
4
1
, and then we'd have something eminently useful.
void clearStack(void); is better (like the others).
I think there is a missing break after clearStack(); The pop() does
not make sense if the stack has been cleared so a fall-though can't
have been intended.
Every other case has a break statement, so I wouldn't see why this one
doesn't need one too.
My big problem with the "solution" is that is does not do what is
intended! I don't interpret the suggestion to rewrite to use scanf
"for the number conversion" to include the use of scanf for the bit it
does badly (reading a single character) and not for the bit it does
well (reading and converting numbers). It seems to be a daft
non-solution.
You claim there's a better sscanf soln waiting to happen here. I don't
disbelieve.
int getop(double *num)
{
int rc;
char s[2];
if ((rc = scanf(" %1[^0-9]", s)) == 1)
return s[0];
else if (rc != EOF && scanf("%lf", num) == 1)
return NUMBER;
else return EOF;
}
If this does the trick, it's a clearly better soln than T&G's. What does s
represent here?
/* This is the simple stack almost straight out of the original */
#define MAXVAL 100
static int sp = 0; /* Next free stack position. */
static double val[MAXVAL];
double push(double f)
{
if (sp < MAXVAL)
return val[sp++] = f;
else {
fprintf(stderr, "Error: stack full.\n");
clear(); /* Following K&R here -- seems reasonable. */
return 0;
}
}
You add static as a storage class modifier. You change the function from
void to double. That would mean that the 101st value gets returned. I'm
not sure that pulling the plug on the whole stack is the best way to deal
with that.
double pop(void)
{
if (sp > 0)
return val[--sp];
else {
fprintf(stderr, "Error: stack empty.\n");
return 0;
}
}
I thought mdh made an error by returning a decimal zero, but that's what
K&R has. Why don't you?
void clear(void)
{
sp = 0;
}
Can you speak to the static nature of sp and this method of clearing the
stack?