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.
Warning: the answers on these pages are crowdsourced, open to anybody to provide/edit after free sign-up, have not all been vetted, might not be correct, let alone optimal, and should not be assumed to be.
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; }