Amber Roxanna
Amber Roxanna

Reputation: 1695

Counting individual word lengths in a string

#include <iostream>
#include <string>
#include <cctype>
size_t countwords(const char *);
using namespace std;

int main()
{
    char a[] =  "Four score and seven years ago";
    float sum = 0.0;
    char j[10];
    string s;
    int size = sizeof(a)/sizeof(char);
    for(int i = 0; i < size; i++){
        if(!isspace(a[i])){
           s += a[i];
        }

        if(isspace(a[i]) and !isspace(a[i + 1])){
            cout << s << " " << s.length() << endl;
            sum += s.length();
            s = "";
        }
    }

    cout << countwords(a);

    return 0;
}

size_t countwords( const char *s )
{
    size_t count = 0;

    while ( *s )
    {
        while ( isspace( *s )) ++s;
        if ( *s ) ++count;
        while ( isalnum( *s )) ++s;
    }


    return ( count );
}

In the main function, I am able to print each word and it's word length. such as four 4, score 5 etc. I am having trouble handling the last word "ago." I don't know how to account for that. Any help would be appreciated.

Output:

Four 4
score 5
and 3
seven 5
years 5
▼  2
6

and yeah, don't know why that black triangle is in the output but this is the exact output.

Upvotes: 1

Views: 2809

Answers (3)

Pete Becker
Pete Becker

Reputation: 76245

std::string word;
std::istringstream str(a);
while (str >> word) {
    sum += str.length();
    std::cout << word << ' ' << word.length << '\n';
}

Upvotes: 0

Dietmar K&#252;hl
Dietmar K&#252;hl

Reputation: 153810

The string you try to inspect is one character longer than you expect:

int size = sizeof(a)/sizeof(char);

This size includes the terminating null character. If I were to deal with the assignment I would either operator on char const* and use the C convention of checking against a terminating null character or I would convert the array into a std::string and deal with iterator and check against the end iterator. I also think that the logic you have to check against the end of a word assumes that words are separated by exactly one space.

Your countwords() function seems to deal with the C convention. Your main() function should check against a[i] being null before using !isspace(static_cast<unsigned char>(a[0])): the countwords() works because isspace(0) and isalnum(0) are false. However, just because 0 isn't a space it means it is part of a word. You should also consider the terminating null character a word separator, i.e., the condition to report the length of a word should be

if(!a[i] || isspace(static_cast<unsigned char>(a[i])))

Upvotes: 1

Praetorian
Praetorian

Reputation: 109119

The terminating NULL character is not considered whitespace, so your second if condition returns false when it encounters the end of the string.

Seems to me the statements within the for statement can be simplified to

if(!isspace(a[i]) && a[i]){
   s += a[i];
} else {
    cout << s << " " << s.length() << endl;
    sum += s.length();
    s = "";
}

Also, breaking the string apart at whitespace can be done easily using an istringstream

char a[] =  "Four score and seven years ago";

std::istringstream ss(a);
std::string s;

while(ss >> s) {
    std::cout << s << ' ' << s.length() << '\n';
}

Upvotes: 1

Related Questions