Search code examples
cgetchar

Wordcount in C that supports singlar letter input


I have some issues with 'wordcount' counting correctly as it missed singular letter such as 'I'.

Essentially if space between a character/symbol or standalone character/symbol will counts a word count.

#include <stdio.h>

int main()
{
    int wordcount;
    int ch;
    char lastch = -1;

    wordcount = 0;

    while ((ch = getc(stdin)) != EOF) {
        if (ch == ' ' || ch == '\n')
        {
            if (!(lastch == ' ' && ch == ' '))
            {
                wordcount++;
            }
        }
        lastch = ch;
    }

    printf("The document contains %d words.", wordcount);
}

Solution

  • You are over-complicating your conditional tests. If I understand your purpose, the only thing you are concerned with is if lastch != ' ' and either (ch == ' ' || ch == '\n').

    Additionally, getchar returns type int. Therefore, ch should be type int to properly detect EOF on all systems.

    Simplifying with those changes, you could do something similar to:

    #include <stdio.h>
    
    int main (void) {
    
        int wordcount = 0,
            lastch = 0,     /* just initialize to zero */
            ch;             /* ch should be an int */
    
        while ((ch = getc (stdin)) != EOF) {
            if (lastch && lastch != ' ' && (ch == ' ' || ch == '\n'))
                wordcount++;
            lastch = ch;
        }
        if (lastch != '\n') /* handle no '\n' on final line */
            wordcount++;
    
        printf ("The document contains %d %s.\n", 
                wordcount, wordcount != 1 ? "words" : "word");
    
        return 0;
    }
    

    Example Use/Output

    $ echo "     " | ./bin/wordcnt
    The document contains 0 words.
    
    $ echo "   t  " | ./bin/wordcnt
    The document contains 1 word.
    
    $ echo "   t t  " | ./bin/wordcnt
    The document contains 2 words.
    

    Note: in order to protect against a corner-case of a file not containing a POSIX eof (e.g. '\n' at the end of the file), you would need to add an additional flag that at least one character was found and check lastch in combination after you exit the loop, e.g.

    #include <stdio.h>
    
    int main (void) {
    
        int wordcount = 0,
            lastch = 0,     /* just initialize to zero */
            ch,             /* ch should be an int */
            c_exist = 0;    /* flag at least 1 char found */
    
        while ((ch = getc (stdin)) != EOF) {
            if (lastch && lastch != ' ' && (ch == ' ' || ch == '\n'))
                wordcount++;
            if (ch != ' ' && ch != '\n')    /* make sure 1 char found */
                c_exist = 1;
            lastch = ch;
        }
        if (c_exist && lastch != '\n')  /* handle no '\n' on final line */
            wordcount++;
    
        printf ("The document contains %d %s.\n", 
                wordcount, wordcount != 1 ? "words" : "word");
    
        return 0;
    }
    

    Corner-case Example

    $ echo -n "   t" | ./bin/wordcnt
    The document contains 1 word.