Reputation: 35
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
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
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