Jump to: navigation, search

The C Programming Language, 2nd Edition, by Kernighan and Ritchie
Exercise 4.08 on page 79

Suppose there will never be more than one character of pushback. Modify getch and ungetch accordingly.



Solution by Steven Huang

/* K&R Exercise 4-8 */
/* Steven Huang */

#include <stdio.h>

int buf = EOF; /* buffer for ungetch */

int getch(void) /* get a (possibly pushed back) character */
{
  int temp;

  if (buf != EOF) {
    temp = buf;
    buf = EOF;
  } else {
    temp = getchar();
  }
  return temp;                          
}
 
void ungetch(int c) /* push character back on input */
{
  if(buf != EOF)
    printf("ungetch: too many characters\n");
  else       
    buf = c;
}
 
int main(void)
{
  int c;

  while ((c = getch()) != EOF) {
    if (c == '/') {
      putchar(c);
      if ((c = getch()) == '*') { 
        ungetch('!');
      }         
    } 
    putchar(c);               
  }
  return 0;
}

Solution by Jesus Alvarez (Category 0)

/* K&R Exercise 4-8 */
/* Jesus Alvarez    */
#include <stdio.h>
#include <string.h>
#include <ctype.h>

int    getch    (void);
void   ungetch  (int);

int main()
{
        char c;

        /*
         * The purpose of getch() and ungetch() is to read characters from
         * getchar() while isdigit or isaplha is true. Once isdigit/isalpha is
         * not true, then reading has gone too far, and it must be pushed back
         * onto the stack for later precessing.
         */
        while ((c = getch()) != EOF) {
                if (isdigit(c)) {
                        /*
                         * Read until !isdigit(), meaning we have read one
                         * character too far.
                         */
                        putchar(c);
                        while(isdigit(c = getch())) {
                                putchar(c);
                        }
                        if (c != EOF) {
                                /* Send it back to the stack for future
                                 * processing. */
                                ungetch(c);
                        }
                } else {
                        /* All other characters. */
                        putchar(c);
                }
        }
        return 0;
}

int  buf = -2;       /* Buffer for getch() */

int getch(void)
{
        int tmp;
        if (buf > -2) {
                tmp = buf;
                buf = -2;
                return tmp;
        }
        return getchar();
}

void ungetch(int c)
{
        if (buf > -2) {
                printf("Ungetch: Too many characters.\n");
        } else {
                buf = c;
        }
}


Solution by menonsahab

/* There are many ways to do this. But the easiest way is to limit the BUFSIZE to 1. No additional code necessary.
Everything remains exactly the same as in K&R. I'm skipping the main() function for brevity. */

#include <stdio.h>
#define BUFSIZE 1

char buf[BUFSIZE];
int bufp = 0;

int getch(void)
{
	return bufp > 0 ? buf[--bufp] : getchar();
}

void ungetch(int c)
{
	if(bufp >= BUFSIZE)
		printf("error: stack is full, can't execute ungetch()\n");
	else
		buf[bufp++] = c;
}

Solution by anonymous

I made a small test program for this modification since I noticed exercise 4-10 requests for getch and ungetch to be removed. Also, exercise 4-9 builds off of only getch and ungetch so this will also be sufficient for that one.

#include <stdio.h>

/*
    Exercise 4-8. Suppose that there will never be more than one character of pushback. Modify getch and ungetch accordingly
*/

int buf = '\0'; // char "buffer" for ungetch. ungetch only handles a single char in the buffer, so no need for the array previously used

int getch(void);
void ungetch(int c);

int main()
{
    ungetch('a');
    printf("%c", getch());
    return 0;
}

// if buf has char, return it. Otherwise return getchar()
int getch(void)
{
    int c;
    if (buf != '\0')
    {
        c = buf;
        buf = '\0';
        return c;
    }
    return getchar();
}

// sets buf to c
void ungetch(int c)
{
    buf = c;
}
Personal tools