I have been reading through the C programming Langauge book and in section 4.3 I am trying to compile and run the code thats provided in pages 76-79. I think I have done exactly what is in the textbook, but its not working as it should.
From some printf's i have found that the numbers that are inputted are not actually being pushed to the stack in val[sp]. instead, when printing out the number, it shows a 0.
Also, the spaces aren't being skipped in
while((s[0] = c = getch()) == ' ' || c == '\t'{
;
}
and so the getop() treats them as a non digit and just returns the space. Because of this the output just prints error unknown command when the spaces are being read.
Also, the ' ' is not being read as a command! So it just returns error unknown command when the program encounters it. I am at a loss as how this is happening given I have copied word for word in the textbook and ran it. I am not sure if this code is out of date and doesn't run on newer machines as well. I am also using CodeBlocks to run this if that helps.
Any help is greatly appreciated!
Here's my code
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#define MAXOP 100
#define NUMBER '0'
int getop(char[]);
void push(double);
double pop(void);
int main()
{
//extern double val[MAXVAL];
int type;
double op2;
char s[MAXOP];
while((type = getop(s)) != EOF){
switch(type){
case NUMBER:
puts("a number");
push(atof(s));
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{
printf("error: zero division");
}
break;
case '\n':
printf("\t%.8g\n", pop());
break;
default:
printf("error unknown command %s\n", s);
break;
}
}
printf("Hello world!\n");
return 0;
}
#define MAXVAL 100
int sp = 0;
double val[MAXVAL];
void push(double f)
{
//extern int sp;
//extern double val[MAXVAL];
if(sp < MAXVAL){
val[ sp] = f;
}
else{
printf("stack full, can't push\n");
}
}
double pop(void)
{
//extern int sp;
//extern double val[MAXVAL];
if(sp > 0){
return val[--sp];
}
else{
printf("stack is empty\n");
return 0.0;
}
}
int getch(void);
void ungetch(int c);
int getop(char s[])
{
int i, c;
while((s[0] = c = getch()) == ' ' || c == '\t'){
;
}
s[1] = '\0';
if(!isdigit(c) && c != '.'){
printf("%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;
}
#define BUFSIZE 100
char buf[BUFSIZE];
int bufp = 0;
int getch(void)
{
//extern int bufp;
//extern char buf[BUFSIZE];
return (bufp > 0) ? buf[--bufp] : getchar();
}
void ungetch(int c)
{
//extern int bufp;
//extern char buf[BUFSIZE];
if(bufp >= BUFSIZE){
printf("ungetch: too many characters\n");
}
else{
buf[ bufp] = c;
}
}
and the output for 3 4 1
I have tried to print out each part (the number when it is being pushed) and also print out the ' ' to see if it is actually being returned as ' '. It is, and I am at a loss as how this is happening.
CodePudding user response:
One problem is that your code has:
void ungetch(int c)
{
//extern int bufp;
//extern char buf[BUFSIZE];
if(bufp >= BUFSIZE){
printf("ungetch: too many characters\n");
}
else{
buf[ bufp] = c;
}
}
The book (p79) has:
void ungetch(int c)
{
if(bufp >= BUFSIZE){
printf("ungetch: too many characters\n");
}
else{
buf[bufp ] = c;
}
}
The difference between bufp and bufp is critical.
It isn't the only problem, but things are closer to working when that's fixed.
You are consistently rewriting
xasxandxasx, and the expressions are not interchangeable. It is very, very important to get those correct.As pointed out by Oka, in the
getop()function, you have (twice):while(isdigit(s[i ] = c = getch())){ ; }where the book has:
while (isdigit(s[ i] = c = getch())) ;In the
push()function, you have:val[ sp] = f;where the book has:
val[sp ] = f;
It is crucial that:
- You copy code accurately.
- You understand the difference between
xandx.
With those extra fixes — meaning changing your code to match what's in the book — the code seems to work, at least on the input 3 4 .
