#include <stdio.h>
#include <string.h> // strtok(), strcmp()
#include <stdlib.h> // fopen(), exit(), EXIT_SUCCESS, EXIT_FAILURE
#include <stdbool.h> // bool, true, false
#define MAX_INPUT (10000+1)
/**********************************************************************
* open_file: Opens a file. *
* Returns true if file opens properly, else false. *
**********************************************************************/
bool open_file(FILE **fp, char filename[])
{
return ((*fp = fopen(filename, "r")) != NULL) ? true : false;
}
/**********************************************************************
* get_data: Counts the number of characters, lines, max line length *
* and words in a file. It uses strtok() to tokenize input *
* and get the number of words. *
**********************************************************************/
void get_data(FILE *fp, int *chars, int *lines, int *max_line_len, int *words)
{
char text[MAX_INPUT] = {'\0'}, *p, line_len = 0;
for (p = text; (*p = getc(fp)) != EOF; p++) {
line_len++;
if (*p == '\n') {
(*lines)++;
if (line_len - 1 > *max_line_len)
*max_line_len = line_len - 1;
line_len = 0;
}
}
*p = '\0'; // cover EOF char
if (line_len > *max_line_len) // in case that file ends without a '\n'
*max_line_len = line_len;
*chars = p - &text[0];
char *x = strtok(text, " \n"); // tokenize text
while (x != NULL) {
(*words)++;
x = strtok(NULL, " \n");
}
}
void help(void)
{
puts("usage: mywc [FILE] [OPTION]...\n"
"Print newline, word, and byte counts for a file.\n\n"
"-c, --bytes print the byte counts\n"
"-m, --chars print the character counts\n"
"-l, --lines print the newline counts\n"
"-L, --max-line-length print the length of the longest line\n"
"-w, --words print the word counts\n"
"--help print help and exit\n");
}
int main(int argc, char *argv[])
{
FILE *file = NULL;
int chars = 0, lines = 0, max_line_len = 0, words = 0;
if (argc == 1 || ! strcmp(argv[1], "--help")) {
help();
exit(EXIT_SUCCESS);
}
if (! open_file(&file, argv[1])) {
printf("%s can't be opened\n", argv[1]);
exit(EXIT_FAILURE);
}
get_data(file, &chars, &lines, &max_line_len, &words);
if (argc == 2) {
printf("byte counts: %d\n", chars * sizeof(char));
printf("characters counts: %d\n", chars);
printf("newline counts: %d\n", lines);
printf("length of the longest line: %d\n", max_line_len);
printf("word counts: %d\n", words);
goto exit_;
}
for (char **p = &argv[2]; *p != NULL; p++) {
if (! strcmp(*p, "-c") || ! strcmp(*p, "--bytes"))
printf("byte counts: %d\n", chars * sizeof(char));
else if (! strcmp(*p, "-m") || ! strcmp(*p, "--chars "))
printf("characters counts: %d\n", chars);
else if (! strcmp(*p, "-l") || ! strcmp(*p, "--lines"))
printf("newline counts: %d\n", lines);
else if (! strcmp(*p, "-L") || ! strcmp(*p, "--max-line-length"))
printf("length of the longest line: %d\n", max_line_len);
else if (! strcmp(*p, "-w") || ! strcmp(*p, "--words"))
printf("word counts: %d\n", words);
else if (! strcmp(*p, "--help")) {
help();
break;
}
else
printf("\"%s\" is not a valid option\n", *p);
}
exit_:
fclose(file);
exit(EXIT_SUCCESS);
}