Number of words in a string.

I am trying to count the number of words in a string. I believe I have it set up right, except it seems to be looping through unlimited times. Why will it not stop?

I am trying to get it to say 1 for each space. (I know I will have to add 1 at the end for the first word, but I am just trying to get this program to do what I want now). It is just looping forever though.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <string>
#include <cstdlib>
#include <cstring>
#include <cmath>

using namespace std;

int main()
{
    char sentence[50];
    char space = ' ';

    cout << "Enter a sentence: ";
    cin.getline(sentence, 50);

    for (int i = 0; i < sentence[i]; i++)
       {
            if (i = space)
                cout << +1;
       }

    return 0;
}
Last edited on
= is not the same as ==


i < sentence[i]
What exactly is that trying to do?
Last edited on
This is the part where I believe it messes up because I am skeptical. I thought that this would start i at 0 (hence int i = 0), and then loop it and look at every character in sentence, starting with 0 (the first one). I don't know how to get it to stop at the end of the user's sentence.
You have it set up wrong.

What do you think is sentence[i]? That would be the character at position i in your string. Each character has its own value:
http://www.asciitable.com/

So basically, your loop will continue as long as i is less than the value of the character in position i of your string. Eventually, i is going to go higher than 50, and then where would you be?
You need to think logically about it. What's the condition you need to stop at? You need to stop when you've examined all the letters. How can you know when that is? Well, in C (and C++), the end of a C-string (which is an array of char) is marked with a zero value. So you need to stop when the letter you're looking at is that zero value:

for (int i = 0; sentence[i]!= 0; i++)

Since this is C++, though, you really should use a C++ string instead of an array of char. C++ strings are proper class objects with class methods such as length

for (int i = 0; i < sentence.length(); i++)

Don't forget, = is not the same as ==.
if (i == space)

Last edited on
Also, the condition inside the loop should actually be

sentence[i] == space

and I'm not sure what

cout << +1

is going to do.
It is interesting was header <cmath> included that you can write the plus before the number 1?

cout << +1;



I would write something as

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>

using namespace std;

int main()
{
    const size_t N = 50;
    char sentence[N];
    const char space = ' ';

    cout << "Enter a sentence: ";
    cin.getline( sentence, N );

    const char *p = sentence;
    size_t count = 0;

    while ( *p )
    {
        while ( *p == space ) ++p;
        if ( *p ) ++count;
        while ( *p && *p != space ) ++p;
    }

    cout << "There are " << count << " words in the sentence\n";

    return 0;
}
Last edited on
I am sorry I fixed the i=space to i==space. That was a silly mistake.

But Machop, from what I understand, the for loop will now say, i=0, while i is less than the length of the (user entered) sentence, iterate 1 i. This should work, but I am getting a compiler error "request for member 'length' in 'sentence'. which is of non-class type 'char[50]'". Any ideas?


and sorry, I fixed the +1 to "1". I was concentrating on the for loop and wasn't paying much attention when I wrote that.
Last edited on
See my previous post. I have updated it.
I am looking at it. I am reading a book and watching youtube videos in order to compliment to book. The book has asked me to do this program, but has not gotten to * yet. Is there a quick explanation for *, or should I continue to read before I finish this program?
Well you can substitute the pointer for your original array. The code will look the following way

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>

using namespace std;

int main()
{
    const size_t N = 50;
    char sentence[N];
    const char space = ' ';

    cout << "Enter a sentence: ";
    cin.getline( sentence, N );

    size_t count = 0;
    size_t i = 0;

    while ( sentence[i] )
    {
        while ( sentence[i] == space ) ++i;
        if ( sentence[i] ) ++count;
        while ( sentence[i] && sentence[i] != space ) ++i;
    }

    cout << "There are " << count << " words in the sentence\n";

    return 0;
}
Last edited on
That makes sense! Now! I did not understand the size_t, but I looked it up. This all makes sense and works perfectly! Thank you!
Also you can use macros. For example

#define SkipSpaces( pos ) while ( sentence[pos] == space ) ++pos
#define ExtractWord( pos ) while ( sentence[pos] && sentence[pos] != space ) ++pos
#define IsEmpty( pos ) ( sentence[pos] == '\0' )

Then the code will look as

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <iostream>

using namespace std;

#define SkipSpaces( pos ) while ( sentence[pos] == space ) ++pos 
#define ExtractWord( pos ) while ( sentence[pos] && sentence[pos] != space ) ++pos 
#define IsEmpty( pos ) ( sentence[pos] == '\0' )

int main()
{
    const size_t N = 50;
    char sentence[N];
    const char space = ' ';

    cout << "Enter a sentence: ";
    cin.getline( sentence, N );

    size_t count = 0;
    size_t i = 0;

    while ( !IsEmpty( i ) )
    {
        SkipSpaces( i );
        if ( !IsEmpty( i ) ) 
        {
            ++count;
            ExtractWord( i );
        }
    }

    cout << "There are " << count << " words in the sentence\n";

    return 0;
}
Last edited on
size_t usually corresponds to unsigned int. So you can use simply type specifier unsigned
Last edited on
This should work, but I am getting a compiler error "request for member 'length' in 'sentence'. which is of non-class type 'char[50]'". Any ideas?


length is a member function of the C++ class string. You're not using that class. You chose to use a C style array of char to hold the input, instead of a string.
Last edited on
Also you can write own class Sentence and overload such operators as ++, <<, >>, and add member functions as empty(), extract_word().:)

For example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Sentence
{
public:
    Sentence() : pos( 0 ) { string[0] = '\0'; }  
// or if you have a new compiler
// Sentence() : pos( 0 ), string( {} ) {}

    Sentence & operator ++()
    {
        if ( string[pos] != '\0' ) ++pos;
        return ( *this );
    }

    bool empty() const { return ( string[pos] == '\0' ); }

//  other member functions
private:
    enum { N = 50 };
    char string[N];
    int pos;
};
Last edited on
Topic archived. No new replies allowed.