|
| 1 | +#include <ctype.h> |
| 2 | +#include <stdio.h> |
| 3 | +#include <stdlib.h> |
| 4 | +#include <string.h> |
| 5 | +#include "functions.h" |
| 6 | + |
| 7 | +/* atoi: convert s to integer (chapter 3) */ |
| 8 | +int atoi(const char *s) |
| 9 | +{ |
| 10 | + int n, sign; |
| 11 | + |
| 12 | + while (isspace(*s)) /* skip whitespace */ |
| 13 | + ++s; |
| 14 | + sign = (*s == '-') ? -1 : 1; |
| 15 | + if (*s == '+' || *s == '-') /* skip sign */ |
| 16 | + ++s; |
| 17 | + for (n = 0; isdigit(*s); ++s) |
| 18 | + n = 10 * n + (*s - '0'); |
| 19 | + return sign * n; |
| 20 | +} |
| 21 | + |
| 22 | +/* atof: convert string s to double (chapter 4) */ |
| 23 | +double atof(const char *s) |
| 24 | +{ |
| 25 | + int sign, expSign; |
| 26 | + double val, power, exponent; |
| 27 | + |
| 28 | + while (isspace(*s)) /* skip whitespace */ |
| 29 | + ++s; |
| 30 | + sign = (*s == '-') ? -1 : 1; |
| 31 | + if (*s == '+' || *s == '-') |
| 32 | + ++s; |
| 33 | + for (val = 0.0; isdigit(*s); ++s) |
| 34 | + val = 10.0 * val + (*s - '0'); |
| 35 | + if (*s == '.') |
| 36 | + ++s; |
| 37 | + for (power = 1.0; isdigit(*s); ++s) { |
| 38 | + val = 10.0 * val + (*s - '0'); |
| 39 | + power *= 10.0; |
| 40 | + } |
| 41 | + if (tolower(*s) == 'e') /* handle scientific notation */ |
| 42 | + ++s; |
| 43 | + expSign = (*s == '-') ? -1 : 1; /* record exponent's sign */ |
| 44 | + if (*s == '+' || *s == '-') |
| 45 | + ++s; |
| 46 | + for (exponent = 0.0; isdigit(*s); s++) /* extract the exponent */ |
| 47 | + exponent = 10.0 * exponent + (*s - '0'); |
| 48 | + while (exponent-- != 0) /* adjust power according to exponent */ |
| 49 | + power = (expSign > 0) ? power / 10: power * 10; |
| 50 | + return sign * val / power; |
| 51 | +} |
| 52 | + |
| 53 | +/* itoa: convert n to characters in s (chapter 3) */ |
| 54 | +void itoa(int n, char *s) |
| 55 | +{ |
| 56 | + int sign; |
| 57 | + |
| 58 | + sign = n; /* record sign */ |
| 59 | + |
| 60 | + do { /* generate digits in reverse order */ |
| 61 | + *s++ = abs(n % 10 + '0'); /* get the next digit */ |
| 62 | + } while ((n /= 10) > 0); /* delete it */ |
| 63 | + if (sign < 0) |
| 64 | + *s++ = '-'; |
| 65 | + *s = '0円'; |
| 66 | + reverse(s - strlen(s)); |
| 67 | +} |
| 68 | + |
| 69 | +/* getLine function: read a line into s, return length (chapter 4) */ |
| 70 | +int getLine(char *s, int lim) |
| 71 | +{ |
| 72 | + int c; |
| 73 | + char *len; |
| 74 | + |
| 75 | + len = s; |
| 76 | + while (--lim > 0 && (c = getchar()) != EOF && c != '\n') |
| 77 | + *s++ = c; |
| 78 | + if (c == '\n') |
| 79 | + *s++ = c; |
| 80 | + *s = '0円'; |
| 81 | + return strlen(len); |
| 82 | +} |
| 83 | + |
| 84 | +/* getop: get next operator or numeric operand (chapter 4) - getch/ungetch version */ |
| 85 | +int getop(char *s) |
| 86 | +{ |
| 87 | + int c; |
| 88 | + char *var; |
| 89 | + |
| 90 | + while (isblank(s[0] = c = getchar())) |
| 91 | + ; |
| 92 | + s[1] = '0円'; |
| 93 | + if (c == '-') /* check sign */ |
| 94 | + if (!isdigit(*++s = c = getchar())) { |
| 95 | + ungetc(c, stdin); |
| 96 | + c = *--s; /* not a sign */ |
| 97 | + } |
| 98 | + if (isalpha(c)) { /* string command */ |
| 99 | + var = s; |
| 100 | + while (isalpha(*++s = c = getchar())) |
| 101 | + ; |
| 102 | + *s = '0円'; |
| 103 | + ungetc(c, stdin); |
| 104 | + return (strlen(var) == 1) ? var[0] : NAME; |
| 105 | + } |
| 106 | + if (!isdigit(c) && c != '.') |
| 107 | + return c; /* not a number */ |
| 108 | + if (isdigit(c)) |
| 109 | + while (isdigit(*++s = c = getchar())) |
| 110 | + ; |
| 111 | + if( c == '.') /* collect fraction part */ |
| 112 | + while (isdigit(*++s = c = getchar())) |
| 113 | + ; |
| 114 | + *s = '0円'; |
| 115 | + ungetc(c, stdin); |
| 116 | + return NUMBER; |
| 117 | +} |
| 118 | + |
| 119 | +/* reverse: reverses the string s in place (chapter 3) */ |
| 120 | +void reverse(char *s) |
| 121 | +{ |
| 122 | + char *p, *q, tmp; |
| 123 | + |
| 124 | + q = s + strlen(s) - 1; |
| 125 | + for (p = s; p < q; ++p, --q) { |
| 126 | + tmp = *p; |
| 127 | + *p = *q; |
| 128 | + *q = tmp; |
| 129 | + } |
| 130 | +} |
| 131 | + |
| 132 | +/* strindex: return index of t in s, -1 if none (chapter 4) */ |
| 133 | +int strindex(const char *s, const char *t) |
| 134 | +{ |
| 135 | + int pos; |
| 136 | + const char *j, *k; |
| 137 | + |
| 138 | + for (pos = 0; *s; ++s, ++pos) { |
| 139 | + for (j = s, k = t; *k && (*j == *k); ++j, ++k) |
| 140 | + ; |
| 141 | + if (k > t && *k == '0円') |
| 142 | + return pos; |
| 143 | + } |
| 144 | + return -1; |
| 145 | +} |
0 commit comments