From bfce8f0d0d828209ec0bec71371ee94a7ad62d3e Mon Sep 17 00:00:00 2001 From: Michael Hunteman Date: Tue, 4 Jul 2023 17:03:53 -0500 Subject: Initial commit --- .gitignore | 1 + four/atof.c | 59 ++++++++++++++++++++++++++++++++++ four/calc.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ four/getch.c | 38 ++++++++++++++++++++++ four/getop.c | 35 +++++++++++++++++++++ four/grep.c | 58 ++++++++++++++++++++++++++++++++++ four/op.c | 42 +++++++++++++++++++++++++ one/char.c | 53 +++++++++++++++++++++++++++++++ one/count.c | 41 ++++++++++++++++++++++++ one/longest.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++ one/power.c | 21 +++++++++++++ one/tab.c | 59 ++++++++++++++++++++++++++++++++++ one/temp.c | 31 ++++++++++++++++++ one/uncom.c | 34 ++++++++++++++++++++ three/conv.c | 65 ++++++++++++++++++++++++++++++++++++++ three/escape.c | 53 +++++++++++++++++++++++++++++++ three/expand.c | 19 +++++++++++ three/search.c | 25 +++++++++++++++ two/bit.c | 68 ++++++++++++++++++++++++++++++++++++++++ two/cond.c | 13 ++++++++ two/conv.c | 49 +++++++++++++++++++++++++++++ two/inc.c | 45 ++++++++++++++++++++++++++ 22 files changed, 994 insertions(+) create mode 100644 .gitignore create mode 100644 four/atof.c create mode 100644 four/calc.c create mode 100644 four/getch.c create mode 100644 four/getop.c create mode 100644 four/grep.c create mode 100644 four/op.c create mode 100644 one/char.c create mode 100644 one/count.c create mode 100644 one/longest.c create mode 100644 one/power.c create mode 100644 one/tab.c create mode 100644 one/temp.c create mode 100644 one/uncom.c create mode 100644 three/conv.c create mode 100644 three/escape.c create mode 100644 three/expand.c create mode 100644 three/search.c create mode 100644 two/bit.c create mode 100644 two/cond.c create mode 100644 two/conv.c create mode 100644 two/inc.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9e5e780 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*a.out 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 +#include +#include + +#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 +#include +#include + +#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 +#include + +#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 +#include + +#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 +#include + +#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 + +#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; + } +} diff --git a/one/char.c b/one/char.c new file mode 100644 index 0000000..91cfc75 --- /dev/null +++ b/one/char.c @@ -0,0 +1,53 @@ +#include + +#define IN 1 /* inside of a word */ +#define OUT 0 /* outside of a word */ + +/* count lines, words, and characters */ +void +wc() +{ + /* + * c must be big enough to hold any value getchar() returns so we use + * int instead of char to hold EOF, an integer defined in stdio + */ + int c, nl, nw, nc, state; + state = OUT; + nl = nw = nc = 0; + while ((c = getchar()) != EOF) { + ++nc; + if (c == '\n') { + ++nl; + } + /* && is higher precedence than || */ + if (c == ' ' || c == '\t' || c == '\n') { + state = OUT; + } else if (state == OUT) { + state = IN; + ++nw; + } + } + printf("%d %d %d\n", nl, nw, nc); +} + +/* print input separated by new lines */ +void +print_word_line() +{ + int c; + while ((c = getchar()) != EOF) { + if (c == ' ' || c == '\t' || c == '\n') { + putchar('\n'); + } else { + putchar(c); + } + } +} + +int +main() +{ + wc(); + /* print_word_line(); */ + return 0; +} diff --git a/one/count.c b/one/count.c new file mode 100644 index 0000000..0f5bb82 --- /dev/null +++ b/one/count.c @@ -0,0 +1,41 @@ +#include + +/* count digits, white space, and others */ +int +main() +{ + int c, i, nwhite, nother; + int ndigit[10]; + int nchar[26]; + nwhite = nother = 0; + + for (i = 0; i < 26; ++i) { + if (i < 10) { + ndigit[i] = 0; + } + nchar[i] = 0; + } + + while ((c = getchar()) != EOF) { + if (c >= '0' && c <= '9') { + ++ndigit[c - '0']; + } else if (c == ' ' || c == '\t' || c == '\n') { + ++nwhite; + } else if (c >= 'a' && c <= 'z') { + ++nchar[c - 'a']; + } else { + ++nother; + } + } + + printf("digits ="); + for (i = 0; i < 10; ++i) { + printf(" %d", ndigit[i]); + } + printf("\nchars ="); + for (i = 0; i < 26; ++i) { + printf(" %d", nchar[i]); + } + printf("\nwhite space = %d\nother = %d\n", nwhite, nother); + return 0; +} diff --git a/one/longest.c b/one/longest.c new file mode 100644 index 0000000..cf19ac9 --- /dev/null +++ b/one/longest.c @@ -0,0 +1,86 @@ +#include + +#define MAXLINE 1024 + +/* + * read a line into s, return length, + * assume length is less than MAXLINE + * and the line number is less than MAXLINE + */ +int +get_line(char s[], int lim) +{ + int c, i; + for (i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; ++i) { + s[i] = c; + } + if (c == '\n') { + /* increment i after assignment */ + s[i++] = c; + } + /* put null character at end of string */ + s[i] = '\0'; + return i; +} + +/* copy from into to */ +void +copy(char to[], char from[]) +{ + int i = 0; + /* '\0' marks end of string */ + while ((to[i] = from[i]) != '\0') { + ++i; + } +} + +/* remove trailing whitespace */ +void +trim(char s[], int i) +{ + /* skip null character and new line */ + i -= 2; + while (i >= 0 && (s[i] == ' ' || s[i] == '\t')) { + --i; + } + s[i] = '\0'; +} + +/* flip characters in string */ +void +reverse(char s[]) +{ + int i = 0; + while (s[i] != '\n') { + ++i; + } + --i; + char c; + for (int j = 0; j < i / 2; ++j) { + c = s[i - j]; + s[i - j] = s[j]; + s[j] = c; + } +} + +/* print longest input line */ +int +main() +{ + char line[MAXLINE], longest[MAXLINE]; + + int len; + int max = 0; + while ((len = get_line(line, MAXLINE)) > 0) { + if (len > max) { + max = len; + copy(longest, line); + } + } + if (max > 0) { + /* trim(longest, max); */ + /* reverse(longest); */ + printf("%s", longest); + } + return 0; +} diff --git a/one/power.c b/one/power.c new file mode 100644 index 0000000..dd2ba2d --- /dev/null +++ b/one/power.c @@ -0,0 +1,21 @@ +#include + +int +power(int m, int n) +{ + int p; + for (p = 1; n > 0; --n) { + p *= m; + } + return p; +} + +int +main() +{ + int i; + for (i = 0; i < 10; ++i) { + printf("%d %d %d\n", i, power(2, i), power(-3, i)); + } + return 0; +} diff --git a/one/tab.c b/one/tab.c new file mode 100644 index 0000000..f9c6dc5 --- /dev/null +++ b/one/tab.c @@ -0,0 +1,59 @@ +#include + +/* XXX: dependent on file size */ +#define MAX 1024 + +void detab() +{ + char detab[MAX]; + + int c, i; + i = 0; + while (i < MAX && (c = getchar()) != EOF) { + if (c == '\t') { + for (int t = 0; t < 8; ++t) { + detab[i + t] = ' '; + } + i += 8; + } else { + detab[i++] = c; + } + } + detab[i] = '\0'; + printf("%s", detab); +} + +void entab() +{ + char entab[MAX]; + + int c, i, s; + i = s = 0; + while (i < MAX && (c = getchar()) != EOF) { + if (c == ' ') { + ++s; + } else { + while (s > 0) { + if (s >= 8) { + entab[i++] = '\t'; + s -= 8; + } else { + entab[i++] = ' '; + --s; + } + } + entab[i++] = c; + } + } + + entab[i] = '\0'; + printf("%s", entab); +} + +int +main() +{ + detab(); + /* entab(); */ + return 0; +} diff --git a/one/temp.c b/one/temp.c new file mode 100644 index 0000000..54c99ba --- /dev/null +++ b/one/temp.c @@ -0,0 +1,31 @@ +#include + +#define LOWER 0 +#define UPPER 300 +#define STEP 20 + +void +temp() +{ + float fahr, cel; + + printf("Fahrenheit-Celsius table\n"); + for (fahr = UPPER; fahr >= LOWER; fahr -= STEP) { + cel = (5.0 / 9.0) * (fahr - 32.0); + /* 3 and 6 characters wide with 1 digit after the dot */ + printf("%3.0f %6.1f\n", fahr, cel); + } + + printf("\nCelsius-Fahrenheit table\n"); + for (cel = LOWER; cel <= UPPER; cel += STEP) { + fahr = 9.0 / 5.0 * cel + 32.0; + printf("%3.0f %6.0f\n", cel, fahr); + } +} + +int +main() +{ + temp(); + return 0; +} diff --git a/one/uncom.c b/one/uncom.c new file mode 100644 index 0000000..455f138 --- /dev/null +++ b/one/uncom.c @@ -0,0 +1,34 @@ +#include + +/* XXX: dependent on file size */ +#define MAX 2048 + +int +main() +{ + char uncomment[MAX]; + int c, i; + i = 0; + while (i < MAX && (c = getchar()) != EOF) { + if (c == '/') { + c = getchar(); + if (c == '*') { + while ((c = getchar()) != '/') { + if (c == '\n') { + putchar('\n'); + } else { + putchar(' '); + } + } + } else if (c == '/') { + while ((c = getchar()) != '\n') { + putchar(' '); + } + putchar('\n'); + } + } else { + putchar(c); + } + } + return 0; +} diff --git a/three/conv.c b/three/conv.c new file mode 100644 index 0000000..d3e654e --- /dev/null +++ b/three/conv.c @@ -0,0 +1,65 @@ +#include +#include + +void +reverse(char s[]) +{ + int i = 0; + while (s[i] != '\0') { + ++i; + } + --i; + char c; + for (int j = 0; j < i / 2; ++j) { + c = s[i - j]; + s[i - j] = s[j]; + s[j] = c; + } +} + +void +itoa(int n, char s[]) +{ + int i, sign; + if ((sign = n) < 0) { + n = -n - 1; + } + i = 0; + do { + s[i++] = n % 10 + '0'; + } while ((n /= 10) > 0); + if (sign < 0) { + s[i++] = '-'; + } + s[i] = '\0'; + reverse(s); +} + +void +itob(int n, char s[], int b) +{ + int i, sign; + if ((sign = n) < 0) { + n = -n; + } + i = 0; + do { + s[i++] = (n % b <= 9) ? n % b + '0' : n % b - 10 + 'a'; + } while ((n /= b) > 0); + if (sign < 0) { + s[i++] = '-'; + } + s[i] = '\0'; + reverse(s); +} + +int +main() +{ + char s[32]; + itoa(INT_MIN, s); + printf("%s\n", s); + itob(380, s, 16); + printf("%s\n", s); + return 0; +} diff --git a/three/escape.c b/three/escape.c new file mode 100644 index 0000000..1f1dfe9 --- /dev/null +++ b/three/escape.c @@ -0,0 +1,53 @@ +#include + +void +ctoe() +{ + int c; + while ((c = getchar()) != EOF) { + if (c == '\\') { + c = getchar(); + switch(c) { + case 'n': + putchar('\n'); + break; + case 't': + putchar('\t'); + break; + default: + putchar(c); + break; + } + } else { + putchar(c); + } + } +} + +void +etoc() +{ + int c; + while ((c = getchar()) != EOF) { + switch(c) { + case '\n': + putchar('\\'); + putchar('n'); + break; + case '\t': + putchar('\\'); + putchar('t'); + break; + default: + putchar(c); + break; + } + } +} + +int +main() +{ + etoc(); + return 0; +} diff --git a/three/expand.c b/three/expand.c new file mode 100644 index 0000000..180cc98 --- /dev/null +++ b/three/expand.c @@ -0,0 +1,19 @@ +#include + +int +main() +{ + int c, p; + while ((c = getchar()) != EOF) { + if (c == '-') { + c = getchar(); + for (++p; p < c + 1; ++p) { + putchar(p); + } + } else { + putchar(c); + } + p = c; + } + return 0; +} diff --git a/three/search.c b/three/search.c new file mode 100644 index 0000000..30426c7 --- /dev/null +++ b/three/search.c @@ -0,0 +1,25 @@ +#include + +int +binsearch(int x, int v[], int n) +{ + int low, high, mid; + low = 0; + high = n - 1; + while (low <= high) { + mid = (low + high) / 2; + if (x < v[mid]) { + high = mid - 1; + } else { + low = mid; + } + } + return -1; +} + +int +main() +{ + binsearch(); + return 0; +} diff --git a/two/bit.c b/two/bit.c new file mode 100644 index 0000000..28f0e7d --- /dev/null +++ b/two/bit.c @@ -0,0 +1,68 @@ +#include + +void +itob(int n) +{ + for (int i = 15; i >= 0; --i) { + int j = n >> i; + if (j & 1) { + printf("1"); + } else { + printf("0"); + } + } + printf("\n"); +} + +/* + * return x with the n bits that begin at position p inverted, leaving the other + * bits unchanged + */ +void +invert(unsigned x, int p, int n) +{ + int i; + i = 0; + while (n > 0) { + i |= 1 << p; + --p; + --n; + } + x ^= i; +} + +/* + * return x with the n bits that begin at position p set to the rightmost n bits + * of y, leaving the other bits unchanged + */ +void +setbits(unsigned x, int p, int n, unsigned y) +{ + x = x >> (p + 1 - n) & ~(~0 << n); + y = y & (~0 << n) | x; + printf("%d %d\n", x, y); + itob(x); + itob(y); +} + +/* count the number of 1-bits */ +int +bitcount(unsigned x) +{ + int b = 0; + while (x != 0) { + /* deletes rightmost 1-bit in x */ + x &= (x - 1); + ++b; + } + return b; +} + +int +main() +{ + /* setbits(5, 2, 3, 16); */ + /* invert(16, 2, 1); */ + printf("%d\n", bitcount(4)); + return 0; +} diff --git a/two/cond.c b/two/cond.c new file mode 100644 index 0000000..5a7b88b --- /dev/null +++ b/two/cond.c @@ -0,0 +1,13 @@ +#include + +int +main() +{ + char s[] = "fOobArBaz"; + for (int i = 0; s[i] != '\0'; ++i) { + (s[i] >= 'A' && s[i] <= 'Z') ? printf("%c", s[i] + 32) + : printf("%c", s[i]); + } + printf("\n"); + return 0; +} diff --git a/two/conv.c b/two/conv.c new file mode 100644 index 0000000..7bf218a --- /dev/null +++ b/two/conv.c @@ -0,0 +1,49 @@ +#include + +int +lower(int c) +{ + if (c >= 'A' && c <= 'Z') { + return c + 'a' - 'A'; + } else { + return c; + } +} + +int +atoi(char s[]) +{ + int i, n; + + n = 0; + for (i = 0; s[i] >= '0' && s[i] <= '9'; ++i) { + n = 10 * n + (s[i] - '0'); + } + return n; +} + +/* convert string of hex digits into int digits */ +int +htoi(char s[]) +{ + int i, n; + + n = 0; + for (i = 0; s[i] >= '0' && s[i] <= 'f'; ++i) { + if (s[i] >= '0' && s[i] <= '9') { + n = 16 * n + (s[i] - '0'); + } else if (s[i] >= 'A' && s[i] <= 'F') { + n = 16 * n + (s[i] - 'A' + 10); + } else if (s[i] >= 'a' && s[i] <= 'f') { + n = 16 * n + (s[i] - 'a' + 10); + } + } + return n; +} + +int +main() +{ + printf("%d\n", htoi("1f")); + return 0; +} diff --git a/two/inc.c b/two/inc.c new file mode 100644 index 0000000..220f025 --- /dev/null +++ b/two/inc.c @@ -0,0 +1,45 @@ +#include + +/* remove s2 chars from s1 */ +void +squeeze(char s1[], char s2[]) +{ + int i, j, k, b; + for (i = j = 0; s1[i] != '\0'; ++i) { + b = 0; + for (k = 0; s2[k] != '\0'; ++k) { + if (s1[i] == s2[k]) { + b = 1; + } + } + if (b == 0) { + s1[j++] = s1[i]; + } + } + s1[j] = '\0'; +} + +/* return first index in s1 where any char in s2 */ +int +any(char s1[], char s2[]) +{ + int i, j; + for (i = 0; s1[i] != '\0'; ++i) { + for (j = 0; s2[j] != '\0'; ++j) { + if (s1[i] == s2[j]) { + return i; + } + } + } + return -1; +} + +int +main() +{ + char s1[] = "foobar"; + char s2[] = "a"; + // squeeze(s1, s2); + printf("%d\n", any(s1, s2)); + return 0; +} -- cgit v1.2.3