0

I am new to C programming and trying to write a code for counting the number of words in a string.Here is my code for counting the number of codes.

    #include<stdio.h> 
    #include<string.h>
    void main() 
    { 
        int count=0,i,len; 
        char str[100]; 
        printf("enter the sentence"); 
        gets(str); 
        len=strlen(str); 
        for(i=0;i<=len;i++) 
        {  
           if(str[i]==' ') 
              count++; 
        } 
        printf("the number of words are :\t%d",count+1); 
    }

When my input is:Here is four words it works fine. it gives output the number of words are : 4

My question is how do I handle "two consecutive spaces" between the word, "space at the beginning" of the input and "space at the last" of the input.

Aatish Sai
  • 3
  • 1
  • 1
  • 5
  • 3
    Note: Do **not** use `gets()`. It is such a security hole it has been deprecated from the language and targeted for removal in the next standard. – WhozCraig Apr 20 '13 at 02:58
  • @WhozCraig I didn't realize that; I have always used it for its simplicity. Can you point me to its replacements? – Anurag Kalia Apr 20 '13 at 03:15
  • @WhozCraig I also use gets() all the time. Can you point out the actual defect i using it? – Aatish Sai Apr 20 '13 at 03:32
  • 2
    [http://insecure.org/stf/smashstack.html](http://insecure.org/stf/smashstack.html) is a great link that goes right into the nitty-gritty. Put simply, the user can input more data than your buffer (str) can hold, overrunning it - if the attacker knows how to exploit it, they can change the next instruction to be executed to that of their own choosing. – ZXcvbnM Apr 20 '13 at 04:05
  • 2
    The point with `gets()` in particular is that you have absolutely **no** way to limit the amount of data read. The recommended replacement is `fgets()` (remember that you can access standard input via the predefined `FILE * stdin` handle). While we're at the subject of deprecated functions, `scanf()` is also considered a poor choice for reading user input, due to its very limited ability to recover from matching errors. – DevSolar Apr 20 '13 at 04:15

8 Answers8

3

Instead of counting spaces, count the first non-space character of each word.

#include<stdio.h> 

int main() 
{ 
    int count=0; 
    char str[100]; 
    printf("enter the sentence"); 
    gets(str);

    char *cur= str;

    for (;;)
    {
        while (*cur == ' ')
        {
            cur++;
        }

        if (*cur == 0)
        {
            break;
        }

        count++;

        while (*cur != 0 && *cur != ' ')
        {
            cur++;
        }
    }

    printf("the number of words are :\t%d",count); 

    return 0;
}
Drew
  • 31
  • 1
0

You can use:

 while(str[i]==' '&&str[i]!=EOF) 
{
    count++;
    i++;
}

instead of your if part. You also need to add these code before the for loop to read the beginning spaces.

Tianyun Ling
  • 1,045
  • 1
  • 9
  • 24
0

I think the loop in the current form may not work properly,

It should be as follows,

    for(i=0;i<len;i++) 
    { 
          if(i!=0)
          {
             if(str[i]==' ') 
               count++; 
          }
    }  

To check the other criteria change the code as follows,

    for(i=0;i<len;i++) 
    { 
             if(str[i]==' ') 
             {  
                if(i!=0)
                {  
                   if(str[i+1]!=' ')
                   {
                      count++;
                   } 
               }   
    }  
Deepu
  • 7,592
  • 4
  • 25
  • 47
  • yeah it works fine but have to make a little change to ignore the last space in case the the input ends with the space.Any ways thank you – Aatish Sai Apr 20 '13 at 03:01
  • Then change the for loop test to i<=n, then it will work fine – Deepu Apr 20 '13 at 03:06
0

Just ignore spaces at the beginning and spaces directly after other spaces, and +1 if there are no spaces at the last.

#include <stdio.h> 
#include <string.h>
// #include <stdlib.h>
int main() // void main is a bad practice
{ 
    int count = 0, i, len, ignoreSpace; 
    char str[100];
    printf("enter the sentence\n"); 
    gets(str); 
    len = strlen(str); 
    ignoreSpace = 1; // handle space at the beginning
    for(i = 0; i < len; i++) // not i<=len
    { 
        if(str[i] == ' '){
            if(!ignoreSpace){
                count++;
                ignoreSpace = 1; // handle two or more consecutive spaces
            }
        }else{
            ignoreSpace = 0;
        }
    }
    if( !ignoreSpace ) // handle space at the last
        count++;
    printf("the number of words are :\t%d\n", count); // +1 is moved to previous line
    // system("pause");
    return 0;
}
johnchen902
  • 9,531
  • 1
  • 27
  • 69
  • Thank you this was what I was looking for. And about your comment on using int main() instead of void, me being a beginner my lecturer is teaching using void can you give me some knowledge about it or just a link where i can learn – Aatish Sai Apr 20 '13 at 03:11
0

You should count the transitions from space to non-space characters + a possible non-space character in the beginning itself.

#include<stdio.h> 
#include<string.h>
int main() 
{ 
    int count=0,i,len, cur_is_spc; 
    char str[100]; 
    printf("enter the sentence"); 
    gets(str); 
    len=strlen(str);

    cur_is_spc = 0;           // 0, if current character is not space. 1, if it is.

    for(i=0; str[i]!='\0'; i++) 
    { 
       if(str[i] != ' ')
       {
           switch(cur_is_spc) // currently holding value for previous character
           {
           case 0: count++; break;    //count the spc->non-spc transitions
           case 1:          break;
           default: cout << "Erroneous value"; exit(1);
           }
           cur_is_spc = 1;    //updated for current character.
       }
       else
       {
           cur_is_spc = 0;    //updated for current character.
       }
    } 

    printf("the number of words are :\t%d",count+1); 
    return 0;
}

Here, I am checking with only spaces. But there can be characters like newline, tab etc. How would your code handle them? Hint: use isspace() function.

/moreover, the transition can be done from non-alphabet characters to alphabet characters if you decide that words are made up of alphabets only. This approach is inherently flexible to suit your needs.

Anurag Kalia
  • 4,668
  • 4
  • 21
  • 28
0

Why not use strtok and bypass it altogether:

int main()
{
    int num_words = 0;
    char    str_one[] = "This string has a trailing space ";
    char    str_two[] = " This string has a preceeding space";
    char    str_three[] = "This string contains  two spaces consecutively  twice!";
    char    delim[] = " ";
    char    *ret;

    /* fgets() for user input as desired... */

    if (( ret = strtok(str_one, delim)) != NULL )
    {
        while ( ret )
        {
            num_words++;
            ret = strtok(NULL, delim);
        }
    }
    else
    {
        /* no spaces, but might contain a word if the string isn't empty */
        if ( str_one[0] != '\0' )
            num_words = 1;
    }

    printf("str_one contains %i words\n", num_words);
    num_words = 0;

    ...

    return 0;
}

And by the way: main should ALWAYS return!!!

ZXcvbnM
  • 611
  • 7
  • 16
0

use strtok and first call of strtok use strtok(string," ") and for rest of calls use strtok(NULL, " \n")

ccc
  • 93
  • 1
  • 3
  • 10
0



One quick way to do this is use strtok and break everything according to a predicate. This function satisfy all your requirements.

#include<stdio.h>
#include<string.h>
int countSpace(char* str){
int counter = 0;
char * newString;
newString= strtok (str, " "); // now the newString has the str except first word
while (newString != NULL){
    counter++; // Put counter here to ignore the newString == NULL 
                // Or just -1 from the counter on main()
    newString= strtok (NULL, " "); //Break the str in to words seperated by spaces

}
return counter;
}
void main(){
    int count=0,i,len;
    char str[100];
    printf("Enter the sentence:\n");
    fgets (str , 100 , stdin);
    count = countSpace(str);
    printf("The number of words are :\t%d\n",count);
    return 0;
}

Thank you

printfmyname
  • 983
  • 15
  • 30