0

I am attempting to extract words from a c string and then compare then with the words in a 2d array and count the number of matching words. I've noticed that some of the string lengths are not what I was expecting and that's probably why numMatches isn't correct but I'm not sure why I'm getting string lengths that don't match. Where am I going wrong here?

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


int main ()
{
    char str[] ="bob amy ted susan";
    char * pch;
    pch = strtok (str," ");
    char arr[4][10] = {"bob", "amy", "susan", "ted"};
    int numMatches = 0;
    int i = 0;
    while (pch != NULL)
    {
        cout<< pch <<endl;
        cout << strlen(arr[i]) << endl;
        if (strcmp(pch,arr[i])==0){
            numMatches++;
        }
        pch = strtok (NULL, " ");
        i++;



    }
    cout << arr[2] << endl;
    cout << numMatches << endl;

    return 0;
}
Output I'm getting...

bob
3
amy
3
ted
5
susan
3
Total Matches : 2

Output I'm expecting...
bob
3
amy
3
ted
3
susan
5
Total Matches : 4
Nicholas
  • 89
  • 6
  • Please post the output your program outputs and post what output did you expect or wanted to have. – KamilCuk Jul 13 '20 at 19:37
  • 1
    What is the output you're getting? What output did you expect? Please [edit] your question to include that. Also please learn how to use a debugger to step through your code statement by statement while monitoring variables and their values, that's how you usually figure out problems like these. – Some programmer dude Jul 13 '20 at 19:37
  • 3
    *Where am I going wrong here?* -- Not using `std::stringstream` to parse, and not using `std::unordered_set` to store the words to search. – PaulMcKenzie Jul 13 '20 at 19:38
  • 2
    Typo: "susan" and "ted" are reversed in the array. So you are printing the length of the wrong strings. Or maybe you meant to reverse them. Either way, the lengths are different. – 001 Jul 13 '20 at 19:40
  • Much can be learned by printing out `arr[i]` along with its size. – user4581301 Jul 13 '20 at 19:40
  • 5
    @JesperJuhl In what universe is `cout << strlen(arr[i]) << endl;` "C, no questions asked" – WhozCraig Jul 13 '20 at 19:40
  • 1
    Please add the expected and actual output and note that you print `pch`, but then the length of `arr[i]`. Maybe your expectations are wrong here. Btw. you tagged this C++, any reason you don't use `std::string`? – Lukas-T Jul 13 '20 at 19:40
  • 1
    [See a more C++ way of doing this](http://coliru.stacked-crooked.com/a/b3297b6345f7353d). – PaulMcKenzie Jul 13 '20 at 19:47
  • "not reproducible" yes it definitively is ... "caused by typos" ... depends a lot on OP's intent; if they want to match the order then yes, it's two words switched, if they want to **count** (`numMatches`...) matches however then it's definitively not a "typo". Leaving it closed because it's probably of not much use to anyone except OP who already has my answer, though. – Daniel Jour Jul 13 '20 at 20:09
  • 1
    @OP Regardless of the language, this is a very bad way for searching if a name is in a list. What if there were thousands of names in the name list? For each name you are searching for, you have to start back at the beginning of the name list. – PaulMcKenzie Jul 13 '20 at 20:10

1 Answers1

1

Go step by step through your code, and "execute" it in your head / on paper:

First iteration:
i == 0
pch == "bob"
arr[i] == arr[0] == "bob"
strlen("bob") == 3
numMatches increased to 1

Second iteration:
i == 1
pch == "amy"
arr[i] == arr[1] == "amy"
strlen("amy") == 3
numMatches increased to 2

Third iteration:
i == 2
pch == "ted"
arr[i] == arr[2] == "susan"
strlen("susan") == 5
numMatches NOT increased, stays at 2

Forth iteration:
i == 3
pch == "susan"
arr[i] == arr[3] == "ted"
strlen("ted") == 3
numMatches NOT increased, stays at 2

Done, pch == NULL

As you see, you're comparing the token (pch) to just one single value of your arr. You probably want a second loop there which loops over arr[i] for all possible values of i. Ideally you should put this loop into its own function, name suggestion isInArr (or matches or ... depends a lot on what this is actually supposed to become in the the end :) )


Some more suggestions:

  • using namespace std; Don't.
  • #include <string.h> This is for C, when including a C header in C++, use #include <cstring>
  • If the purpose of this code is not to learn about C strings and strtok, then better use more C++ idiomatic code, e.g. std::stringstream (example from PaulMcKenzie in case the comment get's lost)
Daniel Jour
  • 15,896
  • 2
  • 36
  • 63
  • *You probably want a second loop there.* I think the problem is one of typo. The OP probably didn't mean to use "ted" and "susan" in mismatching order it the two lines. – R Sahu Jul 13 '20 at 19:54
  • @RSahu Hm, OP is counting matches though, would suggest to me that the order is irrelevant. – Daniel Jour Jul 13 '20 at 19:55
  • 1
    Only the OP knows what their intent was. – R Sahu Jul 13 '20 at 19:56