Pointers and C-string

I'm doing the following assignment :

Write a function which accepts a pointer to a C-string as its argument. It should return the number of words in the C- string. For example, for the C-string “Madison Bumgarner, of the Giants, pitched another gem!” your function should return 8. You may assume the parameter passed is a valid, null- terminated C-string with no newlines or tabs, exactly one space separates each word, and there is at least one word.
int wordCounter(char* str)

I'm trying to fix it, because I got some errors. As long as I fix it, another errors pop up. That's why I'm asking for help on how to fix it properly. I'm new with the use of the pointers

Here is my code :
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
  #include <iostream> //
#include <iomanip>
#include <string>
using namespace std;

int wordCounter(char *str)
{
    int len;
    len = strlen(str);

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

int main()
{

    char *sentence = 'Madison Bumgarner, of the Giants, pitched another gem!';
    cout << strlen(str);

    wordCounter(sentence);

    return 0;
}


Here the output :

 
twelve.cpp:23:22: warning: multi-character character constant [-Wmultichar]
    char *sentence = 'Madison Bumgarner, of the Giants, pitched another gem!';
                     ^
twelve.cpp:23:22: warning: character constant too long for its type
twelve.cpp:23:11: error: cannot initialize a variable of type 'char *' with an rvalue of type 'int'
    char *sentence = 'Madison Bumgarner, of the Giants, pitched another gem!';
          ^          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
twelve.cpp:24:20: error: use of undeclared identifier 'str'
    cout << strlen(str);
                   ^
2 warnings and 2 errors generated.
char is in ''
string is in ""
very important. This is most of your trouble.
also its easier to use array because char* like like 23 has an annoying const on it:
char sentence[] = "whatever words";

<string> is a c++ object not C char array.
<cstring> is what you need.

str is not the name of any variable you created. perhaps you meant sentence?
finally, there is no space for one of the words. 8 words has 7 spaces, 7 words has 6 spaces, etc. look at why.

all that leads to:

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
  #include <iostream> //
#include <iomanip>
#include <cstring>
using namespace std;

int wordCounter(char *str)
{
    int len;
    len = strlen(str);

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

int main()
{

    char *sentence = "Madison Bumgarner, of the Giants, pitched another gem!";
    cout << strlen(sentence) << endl;

    cout << wordCounter(sentence);

    return 0;
}
Last edited on
now that you have something close... things you can play with:
zero is false in c++ and c-strings end in zero byte (character value = 0 as an integer).

and pointers can be added, or incremented, etc.
and booleans and boolean expressions are 0 or 1 valued.
put all that together a bit...
int wordcounter(char *str)
{
int i{1}; //fancy way to say i = 1 initially
for(char * cp = str; *cp; cp++) //*cp says is 'what is this letter's value, if it is zero, stop!"
i+= *cp==' '; //boolean expressions are 1 or 0. add 1 or 0 each loop, if its a space the expression is true: add 1
return i;
}

the above removes the need for length, and it removes the condition to add as well.

not that making it smaller is always 'better'. This is, as I said, just playing, but maybe you will see something useful in there.
count ++; //prefer to count = count+1
count +=3; //prefer to count = count + 3;
Last edited on
Hello siid14,

A little revision on your code:
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
35
36
#include <iostream> //
#include <iomanip>
#include <string>
#include <cstring>  // <--- Added for the C function. "strlen()"

using namespace std;

int wordCounter(char *str)
{
    //int len;
    int len{ strlen(str) };
    int count{};
    
    std::cout << len;
    
    for (int i = 0; i < len; i++)
    {
        if (str[i] == ' ')
            count++;  // <--- Changed.
    }

    return count;
}

int main()
{

    char* sentence{ "Madison Bumgarner, of the Giants, pitched another gem!" };
    
    cout << strlen(sentence) << '\n';

    std::cout << '\n' << wordCounter(sentence);  // <--- Changed.

    return 0;
}
54
54
7 

Single quotes are for single characters. double quotes are for strings.

Line 28 still produces a warning, but the program still runs.

 In function 'int wordCounter(char*)':
11:24: warning: narrowing conversion of 'strlen(((const char*)str))' from 'size_t {aka long unsigned int}' to 'int' inside { } [-Wnarrowing]
 In function 'int main()':
28:78: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]


This is from the shell program here.

The warning can be eliminated. but I am not sure how at the moment.

After a little testing I came up with this:
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
35
36
#include <iostream>
#include <iomanip>
#include <string>
#include <cstring>  // <--- Added for the C function. "strlen()"

using namespace std;

int wordCounter(const char *str)
{
    //int len;
    size_t len{ strlen(str) };  // <--- Changed type.

    std::cout << len;
    
    int count = 0;
    
    for (size_t i = 0; i < len; i++)  // <--- Changed type.
    {
        if (str[i] == ' ')
            count++;
    }

    return count;
}

int main()
{

    const char* sentence{ "Madison Bumgarner, of the Giants, pitched another gem!" };
    
    cout << strlen(sentence) << '\n';

    std::cout << '\n' << wordCounter(sentence);  // <--- Changed.

    return 0;
}


The last problem is in the if statement in the function. The if statement is looking for a space to add to count, but there is no space after the last word only a "\0" to mark the end, so the last word never gets counted.

Andy
Thank you @jonnin, it worked but I did come change on the code you suggested on line 6 and 23 with const char* since string literals are implicitly const.

Without those change I got the following errors :


twelve.cpp:26:13: error: no matching function for call to 'wordCounter'
    cout << wordCounter(sentence);
            ^~~~~~~~~~~
twelve.cpp:6:5: note: candidate function not viable: 1st argument ('const char *') would lose const qualifier
int wordCounter(char *str)
    ^
1 error generated.


Did you compile your code and it worked perfectly or maybe you haven't?

And thank @Andy, it's helpful!

Last edited on
Quick question, is it normal that my compiler gives me the following output :


8%   


I don't understand why??
There is no need to use strlen() - as per jonnin's post above. Just iterate over str until the end:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>

size_t wordCounter(const char* str)
{
	size_t count {(str != nullptr && *str)};

	for (; count && *str; ++str)
		count += *str == ' ';

	return count;
}

int main()
{
	const auto sentence {"Madison Bumgarner, of the Giants, pitched another gem!"};

	std::cout << wordCounter(sentence) << '\n';
}


PS as per comment below, this requires a minimum of C++17
Last edited on
most likely the compiler thinks you have a character instead of an integer for that % character.
without the exact code doing it, I can't say for sure.

I did not use uptight compiler settings. Many compilers will tolerate things that are technically illegal if you do not tell them to use stricter language settings, so it compiled with a warning for me. Since I recommended changing to char array instead of const char *, I left it alone.
Last edited on
The warning is probably because sentence should be of type const char* const

Easier to use const auto! :)
Last edited on
The C++ Shell gives an error because auto resolves std::initializer_list<const char* const>
VS2019 as C++20 gives const auto resolves to const char* const

C++ Shell is only C++14! You need at least C++17 for the update to uniform initialization.

IMO C++shell should be either updated to the latest (C++20) version or retired
Last edited on
Yes, what auto generates is version dependent.
Apart from that it is always a pain to understand code that has auto in it...
Topic archived. No new replies allowed.