typestar

wc_clone.c in C

A word-count clone: read named files or stdin, count lines, words and bytes.

#include <ctype.h>
#include <stdio.h>

typedef struct {
    long lines;
    long words;
    long bytes;
} Counts;

static Counts count_stream(FILE *f) {
    Counts c = {0, 0, 0};
    int in_word = 0;
    int ch;

    while ((ch = fgetc(f)) != EOF) {
        c.bytes++;
        if (ch == '\n') {
            c.lines++;
        }
        if (isspace(ch)) {
            in_word = 0;
        } else if (!in_word) {
            in_word = 1;
            c.words++;
        }
    }
    return c;
}

static void print_counts(Counts c, const char *label) {
    printf("%8ld %8ld %8ld  %s\n", c.lines, c.words, c.bytes, label);
}

int main(int argc, char **argv) {
    if (argc < 2) {
        print_counts(count_stream(stdin), "-");
        return 0;
    }

    Counts total = {0, 0, 0};
    int failures = 0;

    for (int i = 1; i < argc; i++) {
        FILE *f = fopen(argv[i], "rb");
        if (f == NULL) {
            fprintf(stderr, "cannot open %s\n", argv[i]);
            failures++;
            continue;
        }
        Counts c = count_stream(f);
        if (ferror(f)) {
            fprintf(stderr, "error reading %s\n", argv[i]);
            failures++;
        }
        fclose(f);

        print_counts(c, argv[i]);
        total.lines += c.lines;
        total.words += c.words;
        total.bytes += c.bytes;
    }

    if (argc > 2) {
        print_counts(total, "total");
    }
    return failures > 0;
}

How it works

  1. Each file is counted by one pass over its characters.
  2. With no arguments it falls back to reading stdin.
  3. A totals line prints when more than one file was given.

Keywords and builtins used here

The run, in numbers

Lines
67
Characters to type
1075
Tokens
374
Three-star pace
105 tpm

At the three-star pace of 105 tokens a minute, this run takes about 214 seconds.

Type this snippet

Step 1 of 1 in Encore, step 12 of 12 in Files & I/O.

← Previous