#include #include #include #include int getint(int *p); int getfloat(float *p); /* ungetchar: push char c back to input stream */ #define ungetchar(c) ungetc(c, stdin) /* tests getfloat, prints input to output, puts valid numbers * in brackets : n -> [n] */ int main() { float x; int r; while ((r = getfloat(&x)) != EOF) if (!r) { int c; putchar(getchar()); while (!isdigit(c = getchar()) && c != EOF && c != '-' && c != '+') putchar(c); ungetchar(c); } else printf("[%g]", x); return 0; } /* we assert that EOF is negative */ static_assert(EOF < 0, "EOF is not a negative number"); /* ugetint: gets unsigned int from input to n * n must be intialized by caller * takes optional arguments for loop increment * last char read is stored in varvar_c */ #define ugetint(var_c, n, ...) \ do { \ for (; isdigit(var_c = getchar()); __VA_ARGS__) \ n = 10 * (n) + var_c - '0'; \ } while (0) /* getint : gets int from input and overwrites it to p * returns 1 on valid integer, 0 if no integer is found * and EOF on EOF. */ int getint(int *p) { int c; if ((c = getchar()) == EOF) return EOF; /* handle sign */ int sign = (c == '-') ? -1 : ((c == '+') ? 1 : 0); if (sign) c = getchar(); if (!isdigit(c)) { /* not a number */ ungetchar(c); if (sign) ungetchar((sign > 0) ? '+' : '-'); return 0; } *p = c - '0'; ugetint(c, *p); ungetchar(c); *p *= (sign) ? sign : 1; return 1; } #define DEC_SEP X('.') X(',') #define EXP_SEP X('e') X('E') /* getfloat : gets float from input and overwrites it to p * returns 1 on valid integer, 0 if no integer is found * and EOF on EOF. */ int getfloat(float *p) { char flag; int n; if ((flag = getint(&n)) < 1) /* not a number */ return flag; *p = n; int exp, c = getchar(); /* fractional part */ #define X(C) c == C || if (DEC_SEP 0) { n = exp = 0; ugetint(c, n, exp--); *p += n * pow(10, exp); } #undef X /* exponent part */ #define X(C) c == C || if ((EXP_SEP 0) && getint(&exp)) { *p *= pow(10, exp); } else ungetchar(c); return 1; }