Home > Enterprise >  Counting number of words, characters and lines
Counting number of words, characters and lines

Time:10-23

I want to count the number of characters, words and newlines in a program. My code look like this:

#include <stdio.h>

int main() {
    int nw, nl, nc, c;
    nw = nc = nl = 0;
    for (c = getchar(); c != EOF; c = getchar()) {
        if (c == '\n')
              nl;
        if (c != '\n' || c != '\t' || c != ' ') {
            for (c = getchar(); c == '\n' || c == '\t' || c == ' '; c = getchar()) {
                  nc;
            }
              nw;
              nc;
            if (c == '\n')
                  nl;
        } else
              nc;
    }
    printf("%d %d %d", nc, nw, nl);
    return 0;
}

Input:

smith  book
c c   
bug

Output: 9 0 13

What's wrong with this program?
I am a beginner. Forgive if I made any mistake.

CodePudding user response:

There are multiple problems in your code:

  • the test c != '\n' || c != '\t' || c != ' ' is always true. You mean to test if c is either ' ', '\t' or '\n', ie: a word separator, but the expression should be c == '\n' || c == '\t' || c == ' ' or more generally isspace(c).

  • you count the number of newline characters '\n' but you should add 1 if the last line does not end with a newline.

  • similarly, you count a word for each sequence of white space, but you should ignore leading white space.

A simpler way to handle these corner cases is to keep the last character and test for transitions:

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

int main() {
    int nw, nl, nc, c, lastc;
    nw = nc = nl = 0;
    for (lastc = '\n'; (c = getchar()) != EOF; lastc = c) {
        nc  ;
        if (c == '\n')
            nl  ;
        if (isspace(lastc) && !isspace(c))
            nw  ;
    }
    if (lastc != '\n')
        nl  ;
    printf("%d %d %d\n", nc, nw, nl);
    return 0;
}

Since boolean expressions evaluate to 0 or 1, this code can be simplified as:

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

int main() {
    int nw, nl, nc, c, lastc;
    nw = nc = nl = 0;
    for (lastc = '\n'; (c = getchar()) != EOF; lastc = c) {
        nc  ;
        nl  = (c == '\n');
        nw  = (isspace(lastc) && !isspace(c));
    }
    nl  = (lastc != '\n');
    printf("%d %d %d\n", nc, nw, nl);
    return 0;
}

CodePudding user response:

As @erik258 mentioned, enable compiler warnings & read them all. You should add -Wall -Wextra to your compiling flags.

c==('\n'||'\t'||' '); (you seem to have edited this from your original post) is in essence doing a boolean comparison. i.e. c is true if \n, \t or is true, which all three of those technically are in this case.
What you end up with here can be represented as c==(true||true||true) or c==true or more accurately c==1 no matter what the value of c actually is, which isn't what you seem to be after.
Just thought that you might appreciate that clarification.

Another thing you might like to know... The declaration of your loop: for(c=getchar();c!=EOF;c=getchar())
Can be declared more simply as while((c = getchar()) != EOF)

  •  Tags:  
  • c
  • Related