/* * mono.c * * This file contains functions that deal with reading in monomials * (components of polynomials, like -2x^14) from standard input and * returning them in 'mono' structs. */ #include #include "mono.h" /* get a character from stdin, excluding tab and space */ char get_nonwhite_char (void) { char ch; ch = getchar (); while (strchr (" \t", ch) && !feof (stdin)) ch = getchar (); return ch; } /* read a single monomial into the reference parameter t. * return 0 on success, 1 on end of file or end of line */ int read_mono (mono *t) { static char lookahead = ' '; /* always contains the next char */ static int init = 1; /* true if we need to initialize */ int i, /* loop index */ mul; /* 1 or -1, for negative numbers */ char s[100]; /* build up a number in this string */ /* if this is our first time, initialize lookahead from stdin */ if (init) { lookahead = get_nonwhite_char (); init = 0; } /* end of file? return with 1 */ if (feof (stdin)) return 1; /* end of line? return with 1 */ if (lookahead == '\n') return 1; /* assume coefficient is positive */ mul = 1; if (lookahead == '+') { /* if we find a +, we'll just ignore it as a separator */ lookahead = get_nonwhite_char (); } else if (lookahead == '-') { /* if we find a -, negate mul so later we'll know it * was a negative number */ lookahead = get_nonwhite_char (); mul = -mul; } /* get the coefficient. we'll get it by building it up in * s. there might not be any digits, but that will be OK. */ i = 0; /* while the next character is a digit or period ... */ while (strchr ("0123456789.", lookahead)) { /* put it in the string */ s[i++] = lookahead; /* get the next char */ lookahead = getchar (); } /* null terminator for string */ s[i] = 0; if (!i) /* if we didn't get any digits, the coefficient * is assumed to be 1 */ t->coeff = 1.0; else /* otherwise we'll find the value */ sscanf (s, "%lf", &t->coeff); /* if we found a minus sign before, multiply by -1 */ t->coeff *= mul; /* if there is whitespace here, get a nonwhite char */ if (strchr (" \t", lookahead)) lookahead = get_nonwhite_char (); /* if we didn't find x... */ if (lookahead != 'x') { /* but we found something that couldn't be the * next character in a correct polynomial, then * complain and exit. */ if (!strchr (" \t+-\n", lookahead)) { printf ("unexpected input!\n"); exit (1); } /* otherwise, it's just that there's no x and * the power is 0 (coeff * x^0) and we can return */ t->power = 0.0; return 0; } /* if we did find an x, then maybe there's an exponent */ lookahead = get_nonwhite_char (); if (lookahead != '^') { /* or maybe not. then it's just 1. (coeff * x^1) */ t->power = 1.0; return 0; } /* there's an exponent. we'll start reading in digits * and see what it is. */ lookahead = get_nonwhite_char (); i = 0; while (strchr ("-0123456789.", lookahead)) { s[i++] = lookahead; lookahead = getchar (); } s[i] = 0; /* this time, the user told us '^' so there should be something * there. if not, we don't know what to do so we won't handle it :-) */ sscanf (s, "%lf", &t->power); /* prime lookahead for next time */ if (strchr (" \t", lookahead)) lookahead = get_nonwhite_char (); return 0; }