From c9a9de671b27a37cf84a5cb278201f971ef479e4 Mon Sep 17 00:00:00 2001 From: Peter Date: Mon, 27 Sep 2021 19:35:31 +0800 Subject: [PATCH] week 9 mywc all done --- Week 9/3_mywc/debugging.txt | 5 ++ Week 9/3_mywc/mywc.c | 113 ++++++++++++++++++++++++++++-------- 2 files changed, 95 insertions(+), 23 deletions(-) create mode 100644 Week 9/3_mywc/debugging.txt diff --git a/Week 9/3_mywc/debugging.txt b/Week 9/3_mywc/debugging.txt new file mode 100644 index 0000000..7926e98 --- /dev/null +++ b/Week 9/3_mywc/debugging.txt @@ -0,0 +1,5 @@ +Debugging is twice as hard as writing the code in the first place. +Therefore, if you write the code as cleverly as possible, you are, +by definition, not smart enough to debug it. + + --Brian Kernighan diff --git a/Week 9/3_mywc/mywc.c b/Week 9/3_mywc/mywc.c index 665944e..a81645b 100644 --- a/Week 9/3_mywc/mywc.c +++ b/Week 9/3_mywc/mywc.c @@ -45,27 +45,52 @@ #include #include #include +#include -void counter_stats(FILE *file, int *lines, int *words, int *characters) +#define OPTIONS "clLw" + +typedef struct { + int count; + bool print; +} WC_STAT; + +typedef struct { + WC_STAT lines; + WC_STAT words; + WC_STAT characters; + WC_STAT max_characters; +} WC_STATS; + +// ACTUAL COUNTING HERE. +void counter_stats(FILE *file, WC_STATS *stats) { - char buffer[BUFSIZ]; // PROCESS IN CHUNKS + char buffer[BUFSIZ]; + bool word = false; + int line_characters = 0; + while ( fgets(buffer, BUFSIZ, file) != NULL ) { char *c = &buffer[0]; while ( *c != '\0' ) { - // COUNT WORDS + // COUNT WORDS. if (word && isspace(*c)) { - (*words)++; + stats->words.count++; word = false; } else if (!word) { word = true; } - // COUNT CHARACTERS - (*characters)++; - // COUNT NEWLINES + // COUNT CHARACTERS. + stats->characters.count++; + line_characters++; + // COUNT NEWLINES. if ( *c == '\n' ) { - (*lines)++; + if (line_characters > stats->max_characters.count) { + // EXCLUDES NEWLINE IN COUNT (-1). + stats->max_characters.count = line_characters - 1; + } + stats->lines.count++; + line_characters = 0; } c++; } @@ -73,7 +98,7 @@ void counter_stats(FILE *file, int *lines, int *words, int *characters) } // NUMBER OF LINES IN A FILE. -void counter(char *path, int *lines, int *words, int *characters) +void counter(char *path, WC_STATS *stats) { FILE *file; if (path == NULL) { @@ -83,28 +108,70 @@ void counter(char *path, int *lines, int *words, int *characters) } if (file != NULL) { - counter_stats(file, lines, words, characters); + counter_stats(file, stats); } else { fprintf(stderr, "Error reading file.\n"); exit(EXIT_FAILURE); } +} + +void process_options(WC_STATS *options, int argc, char **argv, char **filename) +{ + int option; + while ( (option = getopt(argc, argv, OPTIONS)) != EOF ) { + switch (option) { + case 'c': + options->characters.print = true; + break; + case 'L': + options->max_characters.print = true; + break; + case 'l': + options->lines.print = true; + break; + case 'w': + options->words.print = true; + break; + } + } + + // DEFAULT OPTS. + if (optind == 1) { + options->words.print = true; + options->characters.print = true; + options->lines.print = true; + } + // getopt MOVES THE NON-OPTION ARGUMENTS (FILENAME) TO THE END OF ARGV. + if (optind < argc) { + *filename = argv[optind]; // ONLY USE FIRST FILENAME. + } + +} + +void print_stat(WC_STAT stat, char *fmt_str) +{ + if (stat.print) { + printf(fmt_str, stat.count); + } +} + +void print_stats(WC_STATS *stats) +{ + print_stat(stats->characters, "CHARACTERS %d\n"); + print_stat(stats->words, "WORDS %d\n"); + print_stat(stats->lines, "LINES %d\n"); + print_stat(stats->max_characters, "LINE_MAX_CHARS %d\n"); } int main(int argc, char *argv[]) { - char *file = argv[1]; - // CHECK IF WE ARE ACCEPTING INPUT FROM A PIPE. - if (argc > 2) { - fprintf(stderr, "Usage: mywc [FILE]\n"); - exit(EXIT_FAILURE); - } - - int lines; - int words; - int characters; - counter(argv[1], &lines, &words, &characters); - printf( "LINES %d, WORDS %d, CHARACTERS %d\n", - lines, words, characters ); + WC_STATS *stats = malloc(sizeof(WC_STATS)); + char *file; + + process_options(stats, argc, argv, &file); printf("%s\n", file); + counter(file, stats); + print_stats(stats); + return 0; } \ No newline at end of file