Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does this else-if loop track number of words entered in C

Tags:

c

word-count

I'm learning C using the K&R book, on a windows machine. I am trying out the program(bare bones Unix word count) which counts lines, characters, and words. Although this program correctly counts the number of characters, the no. of lines and words in my output are always 0 and 1, irrespective of what I enter. I also am somewhat stumped by one part of the program, which I'll get to next-

#include<stdio.h>
#define IN 1
#define OUT 0

int main()
{
    int c,state, nc,nw,nl;
    nl=nw=nc=0;
    state=OUT;
    while(c=getchar()!=EOF)
    {
        ++nc;
        if(c=='\n')
            ++nl;   

        if(c=='\n'||c=='\t'||c==' ')
            state=OUT;
        else if(state==OUT)
        {
            state=IN;
            ++nw;
        }
    }

    printf("\n No. of characters, lines and words are : %d,%d,%d\n",nc,nl,nw);
    return 0;

}

From what it looks, this program is using nc, nl and nw, respectively, to count the number of characters, lines and words entered in the input stream. My understanding of the program logic, thus far, is -

  1. IN and OUT are two variables used to indicate the current state of the program. IN indicates that the program is currently 'inside' a word- in other words- no space, newline or tab has been encountered so far in the characters entered. Or so I think.
  2. At the very beginning, before the while loop, the STATE is set to out. This indicates that right now, there is no word encountered.
  3. When the while loop begins, with every character entered(unless it is EOF-Ctrl+Z), the number of character nc is incremented. In the first if statement, if the character is a newline '\n', nl is incremented. This should keep track of the number of lines encountered.
  4. The second if statement is used to keep track of whether the program is currently inside a word or not, by setting the STATE to 0, whenever there is a blank, newline or tab. I've understood the logic thus far.
  5. However, I am completely stumped coming to the else-if. Here, the program checks if STATE is OUT. Now, STATE will be out in two conditions: when the program runs for the first time, and STATE is set to 0 before the while loop. Example- Consider the input WORD. Here, before W is encountered, STATE is set to 0. Now that STATE is 0, and input is W we come to the else if statement. The next input after W is O. So, STATE is set to 1(indicating the program is inside a word), and the word count is incremented.
  6. But, since the original input was WORD, what happens when R is encountered? What is the value of STATE now? Is it still 1 because it was set to 1 inside the last else-if statement? But then again, if that is 1, there is no condition for when STATE is 1.

Lastly, it's obvious that the program is flawed in some way, because in my sample output below, the number of lines and words are always fixed(0 and 1).

hello word
good morning
^Z

 No. of characters, lines and words are : 24,0,1

I understand that my question is very long, but I'm really stumped and looking for answers to two major points:

  • How does the else-if statement logic work.
  • Why is the program throwing incorrect output.

Many thanks for your help

like image 465
Manish Giri Avatar asked Dec 21 '25 01:12

Manish Giri


1 Answers

You are getting wrong input because you are missing parentheses:

while((c=getchar())!=EOF)
      ^           ^

Without them you always compare the return value of getchar() with EOF and assign the result of this comparison to c. That is, c will always be either 1 or 0.

like image 177
cnicutar Avatar answered Dec 22 '25 14:12

cnicutar



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!