diff options
author | zlg <zlg@zlg.space> | 2013-08-19 02:35:49 -0500 |
---|---|---|
committer | zlg <zlg@zlg.space> | 2013-08-19 02:35:49 -0500 |
commit | 8bb191cb2808968db87ce39d45f40c1996690553 (patch) | |
tree | 82aad6a842d64add93cb01d2cef9a77dfeceaaac /ch5 | |
parent | Solve Exercise 5-1: fixed getint() (diff) | |
download | knr-8bb191cb2808968db87ce39d45f40c1996690553.tar.gz knr-8bb191cb2808968db87ce39d45f40c1996690553.tar.bz2 knr-8bb191cb2808968db87ce39d45f40c1996690553.tar.xz knr-8bb191cb2808968db87ce39d45f40c1996690553.zip |
Solve Exercise 5-2: getfloat()
Diffstat (limited to 'ch5')
-rw-r--r-- | ch5/5-02_getfloat.c | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/ch5/5-02_getfloat.c b/ch5/5-02_getfloat.c new file mode 100644 index 0000000..e6f3347 --- /dev/null +++ b/ch5/5-02_getfloat.c @@ -0,0 +1,75 @@ +#include <stdio.h> +#include <math.h> + +/* The C Programming Language: 2nd Edition + * + * Exercise 5-2: Write getfloat, the floating-point analog of getint. What + * type does getfloat return as its function value? + * + * Answer: getfloat should return an integer, since getint's return value is + * only important to check its status, not the value type that it's working + * with. The only real "gotcha" here is making sure to use getch() after + * checking for a decimal point so the resulting loop will actually execute. + */ + +#define BUFSIZE 100 + +int getch(void); +void ungetch(int); +int getfloat(double *); + +char buf[BUFSIZE]; +int bufp = 0; + +int main() { + double foo; + double *bar = &foo; + while (getfloat(bar) > 0) { + printf("%f\n", foo); + } + return 0; +} + +int getfloat(double *pn) { + int c, sign, places; + + 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 (c != '.' && !isdigit(c)) { + return 0; + } + for (*pn = 0.0; isdigit(c); c = getch()) { + *pn = 10.0 * *pn + (c - '0'); + } + if (c == '.') { + c = getch(); // skip the decimal point or the loop won't trigger + for (places = -1; isdigit(c); c = getch()) { + *pn += (double)(c - '0') * pow(10, places--); + } + } + *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; + } +} |