Linux wc command in C
A standard way to do this is to break the function up into smaller 'private' (static) functions, each with one thing to do. One can pass the default to the counting function in case we are not provided the argument. This allows separation of the code which counts and the UI.

Total is always going to be called with (0, 0, 0), it's unnecessary to provide these arguments. In fact, the storage of Total in dynamic memory is probably unnecessary. No need to updateTotal, use of the counters directly is fine. In fact, there is going to be 1 total, might as well make it static.

fgetc returns an int, char ch is not enough to tell EOF, which is -1. You've defined BUF_SIZE, an excellent optimization, but never use it. I'd go from fgetc to fgets. Note that this assumes that the file is text and doesn't contain a '\0' inside, (eg, modified UTF-8.)

You've included getopt and unistd, making your code POSIX C99, but you're not using those. Removing them makes your code more general C99 (now your code will compile on more compilers.)

#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;
#include &lt;ctype.h&gt;
#include &lt;errno.h&gt;

//stores the Total count of lines words and bytes
struct Total {
    size_t lines, words, bytes;
} total;

//count the bytes, lines and words
//gives incorrect results on binary files with embedded 0
//a word is delimited by everything that {isgraph}
//using the unix definition of a text file, {lines = count('\n')}
static int readFile(FILE *fp) {
    char buffer[1024], b;
    int startWord = 1;
    size_t i;
    while(fgets(buffer, (int)sizeof buffer, fp)) {
        i = 0;
        do {
            b = buffer[i++];
            if(b == '\n') {
                /* This will not recognize '\l' in old Mac text files opened
                 with "wb"? Hmm. */
                total.lines++;
                startWord = 1;
            } else if(b == '\0') {
                break;
            } else if(isgraph(b)) {
                //if there's a visible char, there's a word
                if(startWord) total.words++, startWord = 0;
            } else {
                startWord = 1;
            }
        } while(1);
        total.bytes += i;
    }
    return ferror(fp) ? 0 : 1;
}

int main(int argc, char *argv[]) {
    FILE *fp = 0;
    char *fn = "&lt;no file&gt;";
    for(int i = 1; i &lt; argc; i++) {
        fn = argv[i];
        fp = fopen(fn, "r");
        if(!fp || !readFile(fp)) break;
        fclose(fp), fp = 0;
    }
    if(argc &lt;= 1) readFile(stdin);
    if(fp) fclose(fp);
    if(errno) return perror(fn), EXIT_FAILURE;
    /* https://stackoverflow.com/a/2524675/2472827 */
    printf("%zu lines; %zu words; %zu bytes total.\n",
        total.lines, total.words, total.bytes);
    return EXIT_SUCCESS;
}


Some see typedef struct as problematic, and, in my opinion, it's not needed here; see Linux kernel coding style. INT_MAX could be as little as 32,767; it's never going to be less than zero, so I'd prefer unsigned, or size_t in this context. What if there are other chars besides '\n', ' ', '\r', '\t'? I've included &lt;ctype.h&gt; to get rid of the ambiguity. There was a bug counting the word at the end of the line. Now, a line is defined as the number of '\n' (UNIX style.) A word is delimited by isgraph.