aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore6
-rw-r--r--1-13_word-length-histogram.c73
-rw-r--r--1-14_character-freq-histogram.c51
-rw-r--r--1-15_temp-convert-func.c18
-rw-r--r--1-16_longest-line.c52
-rw-r--r--1-17_over-80.c62
-rw-r--r--README.mdown9
7 files changed, 271 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..67f42e5
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,6 @@
+*
+
+!*.c
+!*.h
+!.gitignore
+!README.mdown
diff --git a/1-13_word-length-histogram.c b/1-13_word-length-histogram.c
new file mode 100644
index 0000000..1b4cdc0
--- /dev/null
+++ b/1-13_word-length-histogram.c
@@ -0,0 +1,73 @@
+#include <stdio.h>
+#define IN 1
+#define OUT 0
+#define MINWLENGTH 2
+#define MAXWLENGTH 20
+
+int main(void) {
+ /* Rundown of variables:
+ c = current input char
+ state = inside or outside a word
+ ltrs = letter count
+ wrds = word count
+ lines = you should be shot if you don't know
+ lengths = an array that keeps track of how often words up to x chars long
+ occur.
+ */
+
+ int c, state, ltrs, wrds, lines, wlen;
+ int lengths[MAXWLENGTH];
+ int i;
+ for (i = 0; i <= MAXWLENGTH; ++i) {
+ lengths[i] = 0;
+ }
+
+ ltrs = wrds = wlen = 0;
+ lines = 1;
+ state = OUT;
+ // Capture input until it ends
+ while ((c = getchar()) != EOF) {
+ // If it's whitespace, we've exited a word
+ if (c == '\n' || c == ' ' || c == '\t') {
+ if (state == IN) {
+ ++wrds; // ...and should increase the count.
+ state = OUT;
+ /* Check to see if the word is eligible to be counted. */
+ if (wlen <= MAXWLENGTH) {
+ ++lengths[wlen];
+ }
+ // Reset our word length now.
+ wlen = 0;
+ }
+ /* If it's a new line, we're still out of a word but need to increment the
+ line count */
+ if (c == '\n') {
+ ++lines;
+ }
+ } else {
+ /* If nothing else, we know it's just a random character or a letter. */
+ state = IN;
+ ++wlen;
+ }
+ /* Everything that's input counts as a letter. */
+ ++ltrs;
+ }
+ // This is ugly and I wish I knew a better way to do it.
+ printf("\nWORD LENGTH FREQUENCY\n\n 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75\n");
+ int iter;
+ iter = MINWLENGTH;
+ while (iter <= MAXWLENGTH) {
+ i = lengths[iter];
+ if (i > 0) {
+ printf("%2d | ", iter);
+ while (i > 0) {
+ printf("#");
+ i = i-1;
+ }
+ printf("\n");
+ }
+ ++iter;
+ }
+ printf("%d words, %d chars, %d lines.\n", wrds, ltrs, lines);
+ return 0;
+}
diff --git a/1-14_character-freq-histogram.c b/1-14_character-freq-histogram.c
new file mode 100644
index 0000000..14c4871
--- /dev/null
+++ b/1-14_character-freq-histogram.c
@@ -0,0 +1,51 @@
+#include <stdio.h>
+int main(void) {
+ /* Rundown of variables:
+ c = current input char
+ ltrs = letter count
+ chars = string containing the characters the program will count
+ lengths = the counts for each character
+ */
+
+ int c;
+ int i = 0;
+ char chars[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+ /* cnum is the number of characters found in the above string */
+ int cnum = 0;
+ while (chars[i] != '\0') {
+ cnum += 1;
+ ++i;
+ }
+
+ /* This array need its members to be initialized to zero. */
+ int lengths[cnum];
+ for (i = 0; i <= cnum; ++i) {
+ lengths[i] = 0;
+ }
+
+ // Capture input until it ends
+ while ((c = getchar()) != EOF) {
+ for (i = 0; i < cnum; ++i) {
+ if (c == chars[i]) {
+ lengths[i] += 1;
+ }
+ }
+ }
+ // This is ugly and I wish I knew a better way to do it.
+ printf("\nCHARACTER FREQUENCY\n\n 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75\n");
+ int iter = 0;
+ while (iter <= cnum) {
+ i = lengths[iter];
+ if (i > 0) {
+ printf("%2c | ", chars[iter]);
+ while (i > 0) {
+ printf("#");
+ i -= 1;
+ }
+ printf("\n");
+ }
+ ++iter;
+ }
+ return 0;
+}
diff --git a/1-15_temp-convert-func.c b/1-15_temp-convert-func.c
new file mode 100644
index 0000000..aa59cf6
--- /dev/null
+++ b/1-15_temp-convert-func.c
@@ -0,0 +1,18 @@
+#include <stdio.h>
+
+#define MAX_F 300.0
+#define STEP 20.0
+
+float convert_to_c(float f) {
+ float celsius = (5.0 / 9.0) * (f - 32.0);
+ return celsius;
+}
+
+int main() {
+ printf("FAHRENHEIT CELSIUS\n");
+ float i;
+ for (i = 0.0; i <= MAX_F; i += STEP) {
+ printf("%4.0f %7.3f\n", i, convert_to_c(i));
+ }
+ return 0;
+}
diff --git a/1-16_longest-line.c b/1-16_longest-line.c
new file mode 100644
index 0000000..1f6e556
--- /dev/null
+++ b/1-16_longest-line.c
@@ -0,0 +1,52 @@
+#include <stdio.h>
+
+#define MAXLENGTH 100
+
+int get_line(char s[], int lim) {
+ /* Put as much as possible into a temp string, and count its length */
+ int c, i;
+
+ for (i = 0; i < lim && (c = getchar()) != EOF && c != '\n'; ++i) {
+ s[i] = c;
+ }
+ if (c == '\n') {
+ s[i] = c;
+ ++i;
+ }
+ s[i] = '\0';
+ return i;
+}
+
+void copy(char from[], char to[]) {
+ int i = 0;
+
+ while ((to[i] = from[i]) != '\0') {
+ ++i;
+ }
+}
+
+int main() {
+ int len, max;
+
+ char line[MAXLENGTH];
+ char longest[MAXLENGTH];
+
+ max = 0;
+ while ((len = get_line(line, MAXLENGTH)) > 0) {
+ if (len > max) {
+ max = len;
+ copy(line, longest);
+ }
+ }
+
+ printf("\nThe longest line is %3d characters long.\n", max);
+ printf("----------------------------------------\n");
+ if (max > 0) {
+ printf("%-s", longest);
+ if (max == MAXLENGTH && longest[max - 1] != '\n') {
+ printf("\n");
+ }
+ }
+
+ return 0;
+}
diff --git a/1-17_over-80.c b/1-17_over-80.c
new file mode 100644
index 0000000..dcf7058
--- /dev/null
+++ b/1-17_over-80.c
@@ -0,0 +1,62 @@
+#include <stdio.h>
+
+#define MINLENGTH 80
+
+/* Read as much as possible of a string and return its length. */
+int get_line(char s[]) {
+ int c, i;
+
+ for (i = 0; i < MINLENGTH - 1 && (c = getchar()) != EOF; ++i) {
+ s[i] = c;
+ }
+ if (c == '\n') {
+ s[i] = c;
+ ++i;
+ }
+ s[i] = '\0';
+ return i;
+}
+
+int main() {
+ // longline is used as a boolean that tells us if it's a line worth printing
+ int longline = 0;
+
+ // len is simply a character counter, while c is the character itself.
+ int len, c;
+ char buffer[MINLENGTH];
+
+ while ((c = getchar()) != EOF) {
+ buffer[len] = c;
+
+ /* When we meet the end of the line, we need to print the rest of the line,
+ but only if we're already in a long line. Otherwise, reset our state.
+ */
+ if (c == '\n') {
+
+ if (longline == 1 && len < MINLENGTH - 1) {
+ buffer[len + 1] = '\0';
+ printf("%-s", buffer);
+ }
+
+ len = 0;
+ longline = 0;
+ continue;
+ }
+
+ /* When the buffer has filled up, output its contents! */
+ if (len == MINLENGTH) {
+ buffer[len + 1] = '\0';
+ printf("%-s", buffer);
+ len = 0;
+ longline = 1;
+ continue;
+ }
+
+ /* If neither of the above cases are caught, increment our counter and fetch
+ more data.
+ */
+ ++len;
+ }
+
+ return 0;
+}
diff --git a/README.mdown b/README.mdown
new file mode 100644
index 0000000..7af39e0
--- /dev/null
+++ b/README.mdown
@@ -0,0 +1,9 @@
+As I was reading Kernighan and Ritchie's *The C Programming Language*, I felt
+like I was learning the syntax and other superficial things, but not learning
+the more practical lessons that I was sure I'd run into once I tried to make
+something. So I chose to do the exercises. I didn't start until the middle of
+Chapter 1, but better late than never!
+
+If you have suggestions or pointers, message me! I really want to learn C "the
+right way". It's a fascinating, spartan, pretty language, and I want to become
+good with it.