Hey guys, I am using the code below ot search for words in a text file and count them. I now would like to do something a little more advanced for example if a text file contains
"hello my name is kim" I want to be able to increment a variable everytime the words hello and my appear next to eachother, is there an easy way to do this?

Thanks.

char array [200];
ifstream file;

      while (file >> array)
	   {
			if(strstr(array,"test") != 0)
                        test++;
           }

Dani AI

Generated

A simple, robust way to count occurrences of two words next to each other (for example "hello" followed by "my") is to tokenize the file into words, normalize each token, and compare each token to the previous one. That avoids relying on strstr over a single word buffer (as discovered) and keeps things portable compared to raw C strings. 's suggestion to read full lines can help when you want to search exact substrings, and 's move toward std::string-style code is the right direction for C++.

Here is a compact example that reads word-by-word, strips leading/trailing punctuation, lower-cases tokens, and counts adjacent matches:

#include <fstream>
#include <string>
#include <algorithm>
#include <cctype>
#include <iostream>

static std::string clean(const std::string &s) {
    size_t i = 0, j = s.size();
    while (i < j && std::ispunct((unsigned char)s[i])) ++i;
    while (j > i && std::ispunct((unsigned char)s[j-1])) --j;
    std::string r(s.begin()+i, s.begin()+j);
    std::transform(r.begin(), r.end(), r.begin(), [](unsigned char c){ return std::tolower(c); });
    return r;
}

int main() {
    std::ifstream in("input.txt");
    if (!in) return 1;
    std::string prev, w;
    int count = 0;
    while (in >> w) {
        w = clean(w);
        if (!prev.empty() && prev == "hello" && w == "my") ++count;
        prev = w;
    }
    std::cout << count << '\n';
}

Notes and caveats: this treats "hellomy" as different from "hello my"; it counts overlapping pairs naturally (e.g. "hello my my" counts the first and second adjacent pairs as they occur), and it ignores case and common surrounding punctuation. For more flexible matching (allowing punctuation between words, optional words, or complex patterns) use C++11's std::regex, but token-based comparison is simpler and faster for this use-case. Troubleshooting: verify the file opened, print tokens while debugging, and be careful to cast to unsigned char when calling ctype functions to avoid undefined behavior.

Recommended Answers

All 8 Replies

Can you not use strstr to look for "hello my"? Or are you looking for any combination such as "my hello", hellomy", and so forth? In that case, the easiest way would be to use a regular expression, which C doesn't support as a standard library. You would need to write your own manually or use a third-party library. Alternatively, you can just hardcode a test for every possible combination. Your choice.

Hi thanks for your quick reply I would hardcode each, but i'm not sure what you mean by a regular expression, what is that?

Thanks for your reply.

Thanks, sorry i'm not very good at c++ how would I go about coding that? Could i use my array and the code I have posted above?

>Thanks, sorry i'm not very good at c++
This has nothing to do with C++ since you've shown that you can do a simple string search. At this point it's a problem solving issue. I personally don't think it's terribly difficult to do this:

if ( strstr ( array, "hello my" ) != NULL )
  ++test;
if ( strstr ( array, "hellomy" ) != NULL )
  ++test;
etc...

And since you're probably new to programming, it's unlikely that you'll have an easy time working with regular expressions.

Thanks again for you help, I am just wondering how come its !=NULL rather than !=0?

The code also doesn't seem to be working for me is it because I am reading the file in one word at a time?

>I am just wondering how come its !=NULL rather than !=0?
Both are the same. NULL simply clarifies your intentions of using 0 in a pointer context. But if you use it, be sure to include a header that defines it. In C++ you'll probably want <cstddef> for NULL unless you use other C libraries.

>it because I am reading the file in one word at a time?
Yes. Use getline to read an entire line and it should work better.

>
This has nothing to do with C++ since you've shown that you can do a simple string search. At this point it's a problem solving issue. I personally don't think it's terribly difficult to do this:

if ( strstr ( array, "hello my" ) != NULL )
  ++test;
if ( strstr ( array, "hellomy" ) != NULL )
  ++test;
etc...

And since you're probably new to programming, it's unlikely that you'll have an easy time working with regular expressions.

That is a "C" way of doing things, which is fine :)

Here is one method which is a bit more C++... (Yes OK, it is actually a bit more difficult than Narue's method)

int count(0);
    std::string::const_iterator iter(LineIn.begin());

    while(iter != LineIn.end() )
    {
        iter = std::search(LineIn.begin(), LineIn.end(), 
                           match.begin(), match.end() );
        if (iter != LineIn.end() )
        {
            ++count;
            ++iter;
            std::string s(iter, LineIn.end());
            LineIn=s;
        }
        
    }

LineIn is a std::string - using getline() from a file
match is a std::string - the string to match, eg, "hello my"

This method will not ignore whitespace, and will find multiple matches per string.
Although be careful to make sure that the strings are an exact match, ie, "Hello" != "hello" != "HELLO" != "HeLlO" .. etc.

the easy way around the mismatched strings is to change LineIn and match both 'tolower' (or 'toupper' - whichever floats your boat)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.