greatgamer34
greatgamer34

Reputation: 35

Finding all instances of a word in a string in C++

So I am trying to make a program that gets an input from a text file, and has the user enter the term they want to search for. From there, the file should be printed out with 3 asterisks in front and behind all of the terms.

It works currently, but it only finds the first term in the file, I want it to find all terms. Any help?

Thanks

#include <iostream>
#include <fstream>
#include <string>
#include <cassert>
#include <cstdio>

using namespace std;

int main(void)
{
    int a, i, z, loc;
    string inputFileName;
    string s, term;
    ifstream fileIn;
    char ch;
    cout << "Enter the name of a file of characters: ";
    cin >> inputFileName;
    fileIn.open(inputFileName.data());
    assert(fileIn.is_open() );
    i = 0;

    while (!(fileIn.eof()))
    {
        ch = fileIn.get();
        s.insert(i, 1, ch);     //insert character at position i
        i++;
    }

    cout << s;
    cout << "Enter a word/phrase you want to search for in the file you entered" << endl;
    cin >> term;
    cout << "The word/phrase " << term << " will have '***' before it and after it" << endl;
    z = (int)term.length();
    loc = s.find(term);

    s.insert(loc, 1, '*');
    s.insert(loc+1, 1, '*');
    s.insert(loc+2, 1, '*');

    s.insert(loc+3+z, 1, '*');
    s.insert(loc+4+z, 1, '*');
    s.insert(loc+5+z, 1, '*');
    cout << s;

    return 0;
}

Text output
Enter the name of a file of characters: text.txt

Repair- Determined by the difficulty of the fix, and the parts needed in order for it to work.

Enter a word/phrase you want to search for in the file you entered

the

The word/phrase by will have '***' before it and after it

Repair- Determined by the difficulty of the fix, and the parts needed in order for it to work.

Upvotes: 0

Views: 4703

Answers (2)

Sam van Kampen
Sam van Kampen

Reputation: 1013

std::basic_string::find

Return value
Position of the first character of the found substring or npos if no such substring is found.

(http://en.cppreference.com/w/cpp/string/basic_string/find)

This means you can simply loop std::string::find until its return value is npos, adding the previous substring location plus the substring length as the starting position.

As you also don't want to find words that contain the substring, but merely the substring as a standalone word, I've added some checks at the start of the function. Note: using a regular expression engine may be cleaner at this point.

loc = 0;

while ((loc = s.find(term, loc)) != std::string::npos)
{
    // check for space at start of term, or check
    // for beginning of string
    if (loc != 0 && s[loc - 1] != ' ') {
        loc += z;
        continue;
    }

    // check for space at end of term, or check for end of string
    if (loc != (s.length() - z) && s[loc + z] != ' ') {
        loc += z;
        continue;
    }

    s.insert(loc, 1, '*');
    s.insert(loc+1, 1, '*');
    s.insert(loc+2, 1, '*');

    s.insert(loc+3+z, 1, '*');
    s.insert(loc+4+z, 1, '*');
    s.insert(loc+5+z, 1, '*');

    loc += z;
    loc += 6; // the amount of asterisks added
}

There are also quicker ways to find all substrings, not using the C++ standard library. This question's accepted answer contains one.

Upvotes: 1

user2440647
user2440647

Reputation:

string.find("term") gives you only the first occurrence of the term "term". If your file is not too long, one way to solve the problem is as follows.

int loc[100], i=0;
int pos = string.find("term", 0);
while(pos!=string::npos) {
   loc[i] = pos;
   pos = string.find("term", pos+1);
   i++;
} 

string.find(term, pos) allows you to search for a term in a string on or after the index "pos".

Ofcourse you can create a dynamic array for storing more than 100 locations

Upvotes: 1

Related Questions