tags:

views:

138

answers:

9

The output of characters number is the actual no. plus 3. I don't know why?

This is the code:

void main(void)
{

 int ch,w=0,c=0;
 do
 {
  ch=getche();
  ++c;
  if(ch==32)
  {
      ++w;
      ++c;
  }

 }while(ch!=13);
 printf("\nnum of characters is  %d",c);
 printf("\nnum of words is  %d",w);
        getch();
}
+3  A: 
  ++c;
  if(ch==32)
  {
      ++w;
      ++c;
  }

You have double-counted the space character. Remove the 2nd ++c.

KennyTM
+4  A: 

You're double-counting spaces:

++c;
if(ch==32)
{
    ++w;
    ++c;
}

You already incremented c; you don't need to do it again. You're also counting the newline as a character, and your word count is a count of the number of spaces, which is going to be short one ("foo bar" has two words, but one space). Depending on what exactly you want to check, standard functions like isspace might be easier (but it returns true for things besides ' ')

Michael Mrozek
hehe, first three answers are almost identical :) +1 for all three of you for being fast and having linked brains.
catchmeifyoutry
+7  A: 

You're incrementing c twice for the space character.

Your if statement should be just:

if(ch==32)
    ++w;

You have another subtle bug as well inasmuch as the string hellospcspcthere (with two spaces) will register as three words in your code.

This is how I would have written it to avoid those problems. Note the use of lastch to avoid counting space sequences as multiple words.

int main(void) {
    int ch = ' ', lastch, w = 0, c = 0;

    do {
        lastch = ch;
        ch = getchar();
        ++c;
        if (ch == ' ') {
            if (lastch != ' ') {
                ++w;
            }
        }
    } while (ch != '\n');

    if (lastch != ' ') {
        ++w;
    }

    printf("num of characters is  %d\n",c);
    printf("num of words is  %d\n",w);

    return 0;
}
paxdiablo
Doesn't handle case of input with no spaces (word count should be 1 in that case, not 0)
David Gelhar
Yeah, there were a few edge cases (that one, plus starting with a space) that weren't handled by the original code. I think I've caught them all now :-)
paxdiablo
Instead of `lastch`, I would use an `inword` state variable: `if (ch==' ') { inword=0; } else { if (!inword) {++w; inword=1}}`, but your edited solution works fine too.
David Gelhar
Much of a muchness, I suspect, @David. Both options effectively increment `w` on the transition from word to whitespace.
paxdiablo
@paxdiablo: Rather than keeping track of the last character, I'd rather use a boolean in the `ch == ' '` conditional. This also works better if you decide later to support other whitespace characters like tabs. And it's more readable, in my opinion. Behold, the bikeshed effect. [Edit: Wow, David beat me to this comment by several minutes].
Brian
+2  A: 

You're counting spaces twice.

Also it's easier to read if you use character literals like ch==' ' instead of ch==32

David Gelhar
+1  A: 

Each space is counted twice

Asaf
+3  A: 

Each space is counted twice...

  ++c;
  if(ch==32)
  {
      ++w;
      ++c; // char is counted again
  }

Change code to:

  ++c;
  if(ch==32)
  {
      ++w;     
  }
hkda150
+2  A: 

You're incrementing c twice, if the character read is 32.

ablaeul
+3  A: 

You are adding to c twice when ch==32. Also, you are adding to c when ch==13.

Brian
A: 
void main(void)
{
    int ch,w=0,c=0,lastch=32;
    while((ch = getche()) != 13) //get input and check if it's ENTER key
    {
        ++c;
        if(ch == 32 && lastch != ch) //make sure two continuous spaces are not counted as a word as pointed out by paxdiablo
            ++w;
        lastch = ch;
    }
    if(lastch != 32) //for a word with no space
        ++w;
    printf("\nnum of characters is  %d",c);
    printf("\nnum of words is  %d",w);
    getch();
}

You can consider using char instead of int.

vivek.m