From cabe1a14b31edce1a247c367f8e1d7265abec34e Mon Sep 17 00:00:00 2001 From: Martin Ashby Date: Tue, 7 Feb 2023 22:20:47 +0000 Subject: Chapter 5 --- ex5-1.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 ex5-1.c (limited to 'ex5-1.c') diff --git a/ex5-1.c b/ex5-1.c new file mode 100644 index 0000000..9a43c00 --- /dev/null +++ b/ex5-1.c @@ -0,0 +1,97 @@ +#include +#include +#include + +#define PUSHBACK_MAX 10 +typedef struct { + FILE* stream; + int pushback[PUSHBACK_MAX]; + int pushback_ix; +} StreamWithPushback; + +StreamWithPushback swpb_new(FILE* f) { + StreamWithPushback ret; + ret.stream = f; + ret.pushback_ix = 0; + for (int i=0; ipushback_ix > 0) { + int ch = swpb->pushback[swpb->pushback_ix]; + swpb->pushback_ix--; + return ch; + } + return getc(swpb->stream); +} + +void ungetch(StreamWithPushback* swpb, int ch) { + if (swpb->pushback_ix >= PUSHBACK_MAX) { + fprintf(stderr, "pushback buffer was full!\n"); + exit(1); + } + swpb->pushback[swpb->pushback_ix] = ch; + swpb->pushback_ix++; +} + +/* getint: get next integer from input into *pn */ +int getint(StreamWithPushback* swpb, int *pn) { + int c, sign; + + while (isspace(c = getch(swpb))) {} + + if (!isdigit(c) && c != EOF && c != '+' && c != '-') { + ungetch(swpb, c); + return 0; + } + + sign = (c == '-') ? -1 : 1; + if (c == '+' || c == '-') { + c = getch(swpb); + // If c isn't then a digit, then we don't have a number. + if (!isdigit(c)) { + ungetch(swpb, c); + // Push the sign character back as well, don't consume it + ungetch(swpb, sign == -1 ? '-' : '+'); + return 0; + } + } + + for (*pn = 0; isdigit(c); c = getch(swpb)) { + *pn = 10 * *pn + (c - '0'); + } + *pn *= sign; + + if (c != EOF) { + ungetch(swpb, c); + } + return c; +} + +#ifndef test + +int main(void) { + int p, x; + StreamWithPushback swpb = swpb_new(stdin); + while ((x = getint(&swpb, &p)) != EOF) { + if (x > 0) { + printf("%d\n", p); + } else { + printf("not a number!\n"); + } + } +} + +#else + +#include "CuTest.h" + +// I could write unit tests here, using fmemopen +// instead of reading something off the filesystem. + +// But I can't be bothered. + +#endif \ No newline at end of file -- cgit v1.2.3-ZIG