aboutsummaryrefslogtreecommitdiff
path: root/ch5
diff options
context:
space:
mode:
authorzlg <zlg@zlg.space>2013-08-19 02:35:49 -0500
committerzlg <zlg@zlg.space>2013-08-19 02:35:49 -0500
commit8bb191cb2808968db87ce39d45f40c1996690553 (patch)
tree82aad6a842d64add93cb01d2cef9a77dfeceaaac /ch5
parentSolve Exercise 5-1: fixed getint() (diff)
downloadknr-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.c75
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;
+ }
+}
ss='insertions'>+19 2018-10-06Remove ID field from DBzlg3-38/+46 2018-10-06cli: change "Status" heading to "Progress"zlg2-36/+40 2018-09-29Bump to 0.3alpha5 for PyPIzlg1-1/+1 2018-09-29cli: Add pretty printing to 'list' commandzlg3-17/+107 2018-09-08setup.py: Bump to alpha4 for PyPIzlg1-1/+1 2018-09-08cli: add '--raw' option to list commandzlg2-9/+45 2018-09-08Add remaining filters to vgstash packagezlg1-2/+11 2018-09-04Update LICENSE to match setup.pyzlg1-80/+67 2018-09-03Branch off from master with pytest, tox, clickzlg16-778/+779 2018-03-18Flesh out filter types and ownership statuszlg3-82/+144 2018-03-18README.mdown: break line correctlyzlg1-1/+1 2018-03-18add 'playlog' list filterzlg2-2/+9 2018-03-13Update helpers a bitzlg1-2/+9 2018-03-13Make VGSTASH_DB_LOCATION point to a filezlg2-21/+20 2016-11-18Remove settings from helpers.shZe Libertine Gamer1-5/+0 2016-11-15Correct phrasing in README.Ze Libertine Gamer1-4/+4 2016-11-13DerpZe Libertine Gamer1-0/+1 2016-11-03Improve error handling in shell scriptsZe Libertine Gamer4-3/+23 2016-10-24Correct run_again, add recursionZe Libertine Gamer1-0/+4 2016-10-21Add quotes to correct behavior for arglistZe Libertine Gamer1-1/+1 2016-10-14updater.sh: add recursion, error handlingZe Libertine Gamer1-43/+101 2016-10-14Correct pipe-handling behaviorZe Libertine Gamer1-1/+9 2016-10-12Clarify a method to move between platformsZe Libertine Gamer1-2/+5