Function to count the number of times a specific word appears in a string

  1. I think I am close but I really cannot figure out how to get the function to work properly. I need to have the user type in several lines and display a count of how many times the word "duck" has been used. I am not sure I am using the strstr right either.... any help would be appreciated.
    -----------
    #include <iostream>
    #include <string>
    using namespace std;

    // Write a function to display a count of the number
    // of times the word "duck" appears in an array of strings.

    //Prototype
    int getDuckCount (string word[], int arraySize);

    int main ( )
    {
    // Declaration
    int count;
    string line[100];
    int size = 100;

    // Input
    cout << "Enter some lines to find a count of how many times"
    << " the word duck appears. Hit enter on a blank line to terminate." << endl;
    for (int index = 0; ;index++)
    {
    getline (cin, line[index]);
    if (line[index] == "") break;
    count = getDuckCount (line[], size);
    }

    //Output
    cout << "The word duck appears " << count << " times. Quack!" << endl;
    return 0;
    }

    int getDuckCount (string word[], int arraySize)
    {
    int duckCount = 0;
    char * duck;

    for (int index = 0; ;index++)
    {
    duck = strstr (word[index], "duck");
    if (word[index] == "") break;
    if (word[index] == duck) duckCount++;
    }
    return duckCount;
    }
     
  2. jcsd
  3. mgb_phys

    mgb_phys 8,952
    Science Advisor
    Homework Helper

    You are passing the entire array of lines to getduck each time a new line is entered, so you are recounting the previous lines each time. You should pass just the current line.
    this will also simplify the getduckCount.

    strstr returns a pointer to the first time duck appears in the string, It returns NULL if it never appears which you should check for.
    Once you have found duck in a string you still need to search the rest of the string to see if it appears again. the normal way to do this would be to call strstr again with the pointer to the first occurence incremented.

    ps. in your entering string for loop you could check that index<100.

    pps. If you are using c++ std::string you could use one of the std::string search functions rather than the 'c' strstr.
     

  4. How do I find out about std::string search functions? What are they.

    I modified the code so that it doesn't use arrays... since you said to check one line at a time, I thought this was the approach to do. I can handle it for null definitely.. but I would like to do that last as this is due today and I can do that with little difficulty. It's the part of "call strstr again with the pointer to the first occurence incremented" that I don't understand..

    modified code so far:

    #include <iostream>
    #include <string>
    using namespace std;

    // Write a function to display a count of the number
    // of times the word "duck" appears in an array of strings.

    //Prototype
    int getDuckCount (string word);

    int main ( )
    {
    // Declaration
    int count;
    string line;

    // Input
    cout << "Enter some lines to find a count of how many times"
    << " the word duck appears. Hit enter on a blank line to terminate." << endl;
    for (int index = 0; ;index++)
    {
    getline (cin, line);
    if (line == "") break;
    count = getDuckCount (line);
    }

    //Output
    cout << "The word duck appears " << count << " times. Quack!" << endl;
    return 0;
    }

    //Function to get the number of times "duck" appears
    int getDuckCount (string word)
    {
    int duckCount = 0;
    string * duck;

    duck = strstr (word, "duck");
    if (word == duck) duckCount++;

    return duckCount;
    }
     
  5. Actually I am coming closer
    if I enter on one line dog cat duck duck and on another duck duck duck.... it gives me a count of 3, which means it must be only reading the last line in...

    Did some research and got this:

    #include <iostream>
    #include <string>
    using namespace std;

    // Write a function to display a count of the number
    // of times the word "duck" appears in an array of strings.

    //Prototype
    int getDuckCount (string word);

    int main ( )
    {
    // Declaration
    int count;
    string line;

    // Input
    cout << "Enter some lines to find a count of how many times"
    << " the word duck appears. Hit enter on a blank line to terminate." << endl;
    for (int index = 0; ;index++)
    {
    getline (cin, line);
    if (line == "") break;
    count = getDuckCount (line);
    }

    //Output
    cout << "The word duck appears " << count << " times. Quack!" << endl;
    return 0;
    }

    //Function to get the number of times "duck" appears
    int getDuckCount (string word)
    {
    int duckCount = 0;
    int index = 0;
    for(index = word.find("duck", 0); index != string::npos; index = word.find("duck", index))
    {
    duckCount++;
    index++;
    }

    return duckCount;
    }
     
  6. mgb_phys

    mgb_phys 8,952
    Science Advisor
    Homework Helper

    A 'c' string is a bunch of bytes in memory ending with a zero.
    eg. char line[]="hello duck and duck";
    the value of line[] is a number, a position in memory say 0x1234000
    result = strstr(line,"duck") will return result=0x1234006 ie 6 "duck" starts 6 bytes later in memory than the start of the string.
    The pointer returned by strstr is equivalent to just the original string pointer.
    So you could call strstr again with this pointer.
    strstr(result,"duck") would find the first duck again, since that is at the front of the new string - so you increment result by 1 so it starts searching from the 'u' in duck onward and returns the position of the second duck.
    In practice you would increment it by 4 since you know there can't be another duck less than 4 characters after the first duck - and you have to check that the new search isn't at the end of the string.

    The string.find() function is similair but handles some of the memory stuff for you so it returns the position in the string not the position in memory. See http://www.cplusplus.com/reference/string/string/find.html

    ps. If you are only counting ducks as they are entered do you need to store all the input lines at all? Can you just reuse one string and check each line as it is entered?
     
  7. mgb_phys

    mgb_phys 8,952
    Science Advisor
    Homework Helper

    Edit - ok th eabove applies to your previous post.

    Your new post is the correct way of doing it except.
    You are only storing the number found for each line and then printing the last one.
    You need to add the result of duckCOunt to the total count.
     
  8. I could reuse one string and check each line as it is entered. I will try that. I have class now, but will work on it later. Thanks so much for your help! :)
     
Know someone interested in this topic? Share this thead via email, Google+, Twitter, or Facebook

Have something to add?