aboutsummaryrefslogtreecommitdiff
path: root/ch5
diff options
context:
space:
mode:
authorzlg <zlg@zlg.space>2013-08-13 04:37:02 -0500
committerzlg <zlg@zlg.space>2013-08-13 04:37:02 -0500
commitfcbbe1a17fcb9fa129b737ddb8d72683ec9bfc3b (patch)
treee164081e82c00b980a6e1e4c15da582505c37997 /ch5
parentSolve Exercise 4-14: Swap Macro (diff)
downloadknr-fcbbe1a17fcb9fa129b737ddb8d72683ec9bfc3b.tar.gz
knr-fcbbe1a17fcb9fa129b737ddb8d72683ec9bfc3b.tar.bz2
knr-fcbbe1a17fcb9fa129b737ddb8d72683ec9bfc3b.tar.xz
knr-fcbbe1a17fcb9fa129b737ddb8d72683ec9bfc3b.zip
Solve Exercise 5-1: fixed getint()
Diffstat (limited to 'ch5')
-rw-r--r--ch5/5-01_getint-fixed.c65
1 files changed, 65 insertions, 0 deletions
diff --git a/ch5/5-01_getint-fixed.c b/ch5/5-01_getint-fixed.c
new file mode 100644
index 0000000..8d53ba6
--- /dev/null
+++ b/ch5/5-01_getint-fixed.c
@@ -0,0 +1,65 @@
+#include <stdio.h>
+#include <ctype.h>
+
+/* The C Programming Language: 2nd Edition
+ *
+ * Exercise 5-1: As written, getint treats a + or - not followed by a digit as
+ * a valid representation of zero. Fix it to push such a character back on the
+ * input.
+ */
+
+#define BUFSIZE 100
+
+int getch(void);
+void ungetch(int);
+int getint(int *);
+
+char buf[BUFSIZE];
+int bufp = 0;
+
+int main() {
+ int foo;
+ int *bar = &foo;
+ while (getint(bar) > 0) {
+ printf("%d\n", foo);
+ }
+ return 0;
+}
+
+int getint(int *pn) {
+ int c, sign;
+
+ while (isspace(c = getch())) {
+ }
+ if (!isdigit(c) && c != EOF && c != '+' && c != '-') {
+ ungetch(c);
+ return 0;
+ }
+ sign = (c == '-') ? -1 : 1;
+ if (c == '+' || c == '-') {
+ c = getch();
+ }
+ if (!isdigit(c)) {
+ return 0;
+ }
+ for (*pn = 0; isdigit(c); c = getch()) {
+ *pn = 10 * *pn + (c - '0');
+ }
+ *pn *= sign;
+ if (c != EOF) {
+ ungetch(c);
+ }
+ return c;
+}
+
+int getch(void) {
+ return (bufp > 0) ? buf[--bufp] : getchar();
+}
+
+void ungetch(int c) {
+ if (bufp >= BUFSIZE) {
+ printf("ungetch: Too many characters.\n");
+ } else {
+ buf[bufp++] = c;
+ }
+}