diff options
author | Michael Hunteman <michael@huntm.net> | 2023-07-04 17:03:53 -0500 |
---|---|---|
committer | Michael Hunteman <michael@huntm.net> | 2023-07-06 17:23:45 -0500 |
commit | bfce8f0d0d828209ec0bec71371ee94a7ad62d3e (patch) | |
tree | bdf49ca788ca1ca030d5b1cccfd0c9dffeb3f69f /four |
Initial commit
Diffstat (limited to 'four')
-rw-r--r-- | four/atof.c | 59 | ||||
-rw-r--r-- | four/calc.c | 99 | ||||
-rw-r--r-- | four/getch.c | 38 | ||||
-rw-r--r-- | four/getop.c | 35 | ||||
-rw-r--r-- | four/grep.c | 58 | ||||
-rw-r--r-- | four/op.c | 42 |
6 files changed, 331 insertions, 0 deletions
diff --git a/four/atof.c b/four/atof.c new file mode 100644 index 0000000..86bd651 --- /dev/null +++ b/four/atof.c @@ -0,0 +1,59 @@ +#include <stdio.h> +#include <ctype.h> +#include <math.h> + +#define MAXLINE 128 + +int +get_line(char s[], int lim) +{ + int c, i; + i = 0; + while (--lim > 0 && (c = getchar()) != EOF && c != '\n') { + s[i++] = c; + } + if (c == '\n') { + s[i++] = c; + } + s[i] = '\0'; + return i; +} + +/* convert string to double-precision floating point */ +double +atof(char s[]) +{ + double val, power; + int i, sign; + for (i = 0; isspace(s[i]); ++i); + sign = (s[i] == '-') ? -1 : 1; + if (s[i] == '+' || s[i] == '-') { + ++i; + } + for (val = 0.0; isdigit(s[i]); ++i) { + val = 10.0 * val + (s[i] - '0'); + } + if (s[i] == '.') { + ++i; + } + for (power = 1.0; isdigit(s[i]); ++i) { + val = 10.0 * val + (s[i] - '0'); + power *= 10.0; + } + if (s[i] == 'e' || s[i] == 'E') { + return sign * val / power * pow(10, s[++i] - '0'); + } + return sign * val / power; +} + +int +main() +{ + double sum; + char line[MAXLINE]; + sum = 0; + while (get_line(line, MAXLINE) > 0) { + printf("\t%g\n", sum += atof(line)); + } + return 0; +} diff --git a/four/calc.c b/four/calc.c new file mode 100644 index 0000000..cb484ad --- /dev/null +++ b/four/calc.c @@ -0,0 +1,99 @@ +#include <stdio.h> +#include <stdlib.h> +#include <math.h> + +#define MAXOP 100 +#define NUMBER '0' + +int getop(char[]); +void push(double); +double pop(void); +double peek(); +void ungets(); + +int +main() +{ + int type, var; + double op1, op2, r; + char s[MAXOP]; + char v[26]; + + /* reverse Polish calculator */ + while ((type = getop(s)) != EOF) { + switch (type) { + case NUMBER: + push(atof(s)); + break; + case '+': + push(pop() + pop()); + break; + case '*': + push(pop() * pop()); + break; + /* to guarantee the right order, the first value must be stored */ + case '-': + op2 = pop(); + push(pop() - op2); + break; + case '/': + op2 = pop(); + if (op2 != 0.0) { + push(pop() / op2); + } else { + printf("error: zero divisor\n"); + } + break; + case '%': + op2 = pop(); + op1 = pop(); + if (op1 >= 0.0 && op2 >= 0.0) { + push((int)op1 % (int)op2); + } else if (op1 < 0.0 || op2 < 0.0) { + push(0); + } else { + printf("error: zero divisor\n"); + } + break; + /* print without popping */ + case 'p': + printf("%f\n", peek()); + break; + /* duplicate */ + case 'd': + op2 = peek(); + push(op2); + break; + /* swap top two elements */ + case 's': + op2 = pop(); + op1 = pop(); + push(op2); + push(op1); + break; + case '=': + pop(); + if (var > 'a' && var < 'z') { + v[var - 'a'] = pop(); + } + case '\n': + r = pop(); + printf("\t%.8g\n", r); + break; + case 'u': + ungets(); + break; + default: + if (type == 'R') { + push(r); + } else if (type >= 'a' && type <= 'z') { + push(v[type - 'a']); + } else { + printf("error: unknown command %s\n", s); + } + break; + } + var = type; + } + return 0; +} diff --git a/four/getch.c b/four/getch.c new file mode 100644 index 0000000..84582ce --- /dev/null +++ b/four/getch.c @@ -0,0 +1,38 @@ +#include <stdio.h> +#include <string.h> + +#define BUFSIZE 101 + +char buf[BUFSIZE]; +int bufp = 0; + +/* + * deliver the next character to be considered + * reading from the buffer if it contains a character + * and calling getchar if the buffer is empty + */ +int +getch(void) +{ + return (bufp > 0) ? buf[--bufp] : getchar(); +} + +/* remember the characters put back on the input */ +void +ungetch(int c) +{ + if (bufp >= BUFSIZE) { + printf("ungetch: too many characters\n"); + } else { + buf[bufp++] = c; + } +} + +void +ungets(char s[]) +{ + int l = strlen(s); + while (l) { + ungetch(s[--l]); + } +} diff --git a/four/getop.c b/four/getop.c new file mode 100644 index 0000000..8870895 --- /dev/null +++ b/four/getop.c @@ -0,0 +1,35 @@ +#include <stdio.h> +#include <ctype.h> + +#define NUMBER '0' + +int getch(void); +void ungetch(int); + +/* get next operator or numeric operand */ +int +getop(char s[]) +{ + int i, c; + + while((s[0] = c = getch()) == ' ' || c == '\t'); + s[1] = '\0'; + /* not a number */ + if (!isdigit(c) && c != '.') { + return c; + } + i = 0; + /* collect integer part */ + if (isdigit(c)) { + while (isdigit(s[++i] = c = getch())); + } + /* collect fraction part */ + if (c == '.') { + while (isdigit(s[++i] = c = getch())); + } + s[i] = '\0'; + if (c != EOF) { + ungetch(c); + } + return NUMBER; +} diff --git a/four/grep.c b/four/grep.c new file mode 100644 index 0000000..7e6b4db --- /dev/null +++ b/four/grep.c @@ -0,0 +1,58 @@ +#include <stdio.h> +#include <string.h> + +#define MAXLINE 1024 + +int +get_line(char s[], int lim) +{ + int c, i; + i = 0; + while (--lim > 0 && (c = getchar()) != EOF && c != '\n') { + s[i++] = c; + } + if (c == '\n') { + s[i++] = c; + } + s[i] = '\0'; + return i; +} + +int strindex(char s[], char t[]) +{ + int i, j, k; + for (i = 0; s[i] != '\0'; ++i) { + for (j = i, k = 0; t[k] != '\0' && s[j] == t[k]; ++j, ++k); + if (k > 0 && t[k] == '\0') { + return i; + } + } + return -1; +} + +int strrindex(char s[], char t[]) +{ + int i, j, k; + for (i = strlen(s) - 1; i > 0; --i) { + for (j = i, k = strlen(t) - 1; k > 0 && s[j] == t[k]; --j, --k); + if (t[k] == t[0]) { + return i; + } + } + return -1; +} + +int +main() +{ + char line[MAXLINE]; + char pattern[] = "ould"; + int found = 0; + while (get_line(line, MAXLINE)) { + if (strrindex(line, pattern) >= 0) { + printf("%s", line); + ++found; + } + } + return found; +} diff --git a/four/op.c b/four/op.c new file mode 100644 index 0000000..f8e96ed --- /dev/null +++ b/four/op.c @@ -0,0 +1,42 @@ +#include <stdio.h> + +#define MAXVAL 100 +#define NUMBER '0' + +int sp = 0; +double val[MAXVAL]; + +void +push(double f) +{ + if (sp < MAXVAL) { + val[sp++] = f; + } else { + printf("error: stack full, can't push %g\n", f); + } +} + +double +pop(void) +{ + if (sp > 0) { + return val[--sp]; + } else { + printf("error: stack empty\n"); + return 0.0; + } +} + +double +peek() +{ + return val[sp - 1]; +} + +void +clear() +{ + while (sp) { + val[sp--] = 0; + } +} |