问题描述
这是 K&R 教科书中 rpn 计算器的代码,我想让计算器处理负数,我该怎么做?我尝试修改 case'-' 和 ggetop,因为我试图获取下一个字符来检查它是否是数字,结果是 ggetop 和 ggetch 自动跳过了空格。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
#define MAXVAL 100
#define MAXOP 100
#define NUMBER '0'
#define BUFSIZE 100
int sp = 0;
double val[MAXVAL];
char buf[BUFSIZE];
int bufp = 0;
double aatof(char []);
void push(double);
double pop(void);
int ggetop(char []);
int ggetch(void);
void unggetch(int);
int main()
{
int type;
double op2;
int op3;
char s[MAXOP];
while ((type = ggetop(s)) != EOF)
{
switch (type)
{
case NUMBER:
push(aatof(s));
break;
case '+':
push(pop() + pop());
break;
case '*':
push(pop() * pop());
break;
case '-':
op3= ggetch();
if (isdigit(ggetch())) {
printf("%s",s);
push(0 - aatof(s));
break;
}
else {
printf("%s",6);
op2 = pop();
push(pop() - op2);
break;
}
case '/':
op2 = pop();
if (op2 != 0.0)
push( pop() / op2);
else
printf("error: zero divisor\n");
break;
case '%':
op3 = (int)pop();
if (op3 != 0)
push((int)pop() % op3);
else
printf("error: zero divisor\n");
break;
case '\n':
printf("\t%.8g\n",pop());
break;
default:
printf("error: unkNown command %s\n",s);
break;
}
}
return 0;
}
int ggetop(char s[])
{
int i,c;
while ((s[0] = c = ggetch()) == ' ' || c == '\t')
;
s[1] = '\0';
if (!isdigit(c) && c != '.')
return c;
i = 0;
if (isdigit(c))
while (isdigit(s[++i] = c = ggetch()))
;
if (c == '.')
while (isdigit(s[++i] = c = ggetch()))
;
s[i] = '\0';
if (c != EOF)
unggetch(c);
return NUMBER;
}
int ggetch(void)
{
return (bufp > 0) ? buf[--bufp] : getchar();
}
void unggetch(int c)
{
if (bufp >= BUFSIZE)
printf("unggetch: too many characters\n");
else
buf[bufp++] = c;
}
double aatof(char s[])
{
double val,power;
int i,sign;
for (i = 0; isspace(s[i]); i++)
;
sign = (s[i] == '-') ? -1 : 1;
if (s[i] == '+' || s[i] == '-')
i++;
for (val = 0.0; isdigit(s[i]); i++)
val = 10.0 * val + (s[i] - '0');
if (s[i] == '.')
i++;
for (power = 1.0; isdigit(s[i]); i++)
{
val = 10.0 * val + (s[i] - '0');
power *= 10.0;
}
return sign * val / power;
}
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;
}
}
解决方法
ggetop()
可以进行一些返工
int ggetop(char s[]) {
...
// while ((s[0] = c = ggetch()) == ' ' || c == '\t');
while (isspace( (c = ggetch()) )) ;
// add
int sign = c;
if (sign == '-' || sign == '+') {
c = ggetch();
}
...
return sign == '-' ? -NUMBER : NUMBER;
}