C++ | Searching Word In A Text File | PART-2

Hello peeps! Lord Hypersonic greets you. Today I am presenting you the second part of word finder in file program in c++.  In the previous part of the program, there was a little bug in the program about which we will discuss later in this article and we will also discuss how you can yourself fix that bug.
Before discussing bug, first, let us discuss this program. In this program, you have to enter the full name of the file, by full name I mean with location/filename.filetype

location can be anything where your file is saved.
filename.filetype is the name of file and extension of the file.
for example, C:/Users/Lord Hypersonic/Documents/MyFile.txt
After you have entered the file name, it will check the existence of the provided file. If the file exists then it will ask the user to enter the word which the user want to find in the file.
If that word is present in the file then it will print the positions of the word at which that word is present and if the word is not present it will print that word is not present in the file.
It's so simple.

Now let us discuss our previous version of the program. After that, we will discuss the algorithm of this version of the program.

BUG in the previous version of the program and fix it.

The bug in the previous version of the program was that it was case sensitive. That means when you ask the program to find the positions of the word "find" it will only find the position of "find" only and if there is "Find" or "FIND" it will not detect that. 
Fixing this bug is easy, just you have to convert the input line from file to lower case, so even if user type "FIND" it will also find the position of "find", "Find" or "FIND" and any type of upper case and lower case combinations.


Now let us see what I have done.

The algorithm of the 2nd version of the program.

So I have created two functions for finding positions of the substring in a string. The first function is for splitting the string from space and storing the obtained string into an array of string, also this function will return that array of string so that we can use that array in our other functions.
The second function is for finding the positions of the substring from the string and storing the values in an array of integer. This function also returns the array of integer which stores positions of the substring in the string, and we are going to use this function to find the position of the word entered by the user from the line taken from the file.

We have 3 global variables (noOfSpaces, sizeOfAr, sizeOfPositions, found), we have created these global variables so that when one function manipulate the values of these variables other functions can use these values in there processing.

Now I am providing the source code, I have tried to make it as simple as I can so that you people can understand what is happening. If still, you are not able to understand anything then you can ask me on Facebook, Instagram or on Discord.

Why I am doing so many things if I can fix the bug by adding two lines.

I have changed the algorithm of the whole program even if I was able to fix it by adding two lines of code because "find" function was only giving one location of the substring whereas my function is providing the whole array of positions at which substrings are present in the string. It becomes more convenient to get all the positions of the substring in the string.

Source Code

/*
Program: Find word in a file
Description: Tells the positions of word entered by the user in the file provided by the user
Author: Lord Hypersonic
Email: lordhypersonic.522@gmail.com
Website: www.lordhypersonic.blogspot.com
*/
#include <iostream>
#include <string>
#include <fstream>
#include <ctype.h>
#include <conio.h>

using namespace std;

int noOfSpaces = 0,sizeOfAr = 0, sizeOfPositions = 0, found = 0;

//function to split strings from <space>
string *splitString(string sentence)
{
    int SLen = sentence.size();
    for (int i = SLen; i >= 0; i--) //removing extra space from the end of the string.
    {
        if (sentence[i] != ' ')
            break;
        sentence.resize(sentence.size() - 1);
    }
    for (int i = 0; i < SLen; i++) //counting number of spaces present in the string
    {
        if (sentence[i] == ' ')
            noOfSpaces++;
    }
    sizeOfAr = noOfSpaces + 1;
    sentence.push_back(' ');
    string *Ar = new string[sizeOfAr];
    int pos = 0, ArIndex = 0;
    while ((pos = sentence.find(' ')) != string::npos) //splitting string
    {
        string token = sentence.substr(0,pos);
        for (int i = 0; i < token.size(); i++) //converting each character of the string obtained into lower case alpha
        {
            if (isupper(token[i]))
                token[i] = tolower(token[i]);
        }
        Ar[ArIndex] = token; //adding the obtained string to array of string.
        sentence.erase(0,pos + 1);
        ArIndex++;
    }
    return Ar;
}

//function  to find position of the wordToFind in the sentence
int *FindPositionOfSubString(string sentence, string wordToFind)
{
    string *word = splitString(sentence);
    int position = 0, postionsIndex = 0;
    for (int i = 0; i < sizeOfAr; i++) //count number of times wordToFind is present in the string sentence.
    {
        int pos = 0;
        if (word[i].size() > wordToFind.size())
        {
            pos = word[i].find(wordToFind);
            if (pos != string::npos)
            {
                sizeOfPositions++;
                found = 1;
            }
        }
        if (word[i].size() == wordToFind.size())
        {
            if (word[i] == wordToFind)
            {
                sizeOfPositions++;
                found = 1;
            }
        }
    }
    int *positions = new int[sizeOfPositions];
    for (int i = 0; i < sizeOfAr; i++) //finding positions of wordToFind in the string sentence and adding the positions to array of integer.
    {
        int pos;
        if (word[i].size() > wordToFind.size())
        {
            pos = word[i].find(wordToFind);
            if (pos != string::npos)
            {
                position = position + pos;
                positions[postionsIndex] = position + 1;
                postionsIndex++;
                for (int j = pos; j < word[i].size() + 1; j++)
                    position++;
            }
            else
            {
                position = position + word[i].size() + 1;
            }
        }
        if (word[i].size() == wordToFind.size())
        {
            if (word[i] == wordToFind)
            {
                positions[postionsIndex] = position + 1;
                position = position + word[i].size() + 1;
                postionsIndex++;
            }
            else
            {
                position = position + word[i].size() + 1;
            }
        }
        if (word[i].size() < wordToFind.size())
        {
            position = position + word[i].size() + 1;
        }
    }
    delete word;
    return positions;
}

int main()
{
    string wordToFind, fileName, line;
    int lineNumber = 0, F = 0;
    while (true)
    {
        lineNumber = 0; F = 0;
        cout<<"Enter the full name of the file: "; getline(cin,fileName);
        ifstream file (fileName.c_str());
        if (file)
        {
            cout<<"Enter the word to find in the file: "; getline(cin,wordToFind);
            for (int i = 0; i < wordToFind.size(); i++)
                if (isupper(wordToFind[i]))
                    wordToFind[i] = tolower(wordToFind[i]);
            cout<<endl<<"============================================================================="<<endl;
            cout<<"Word \""<<wordToFind<<"\" is present at:- "<<endl;
            while (getline(file,line))
            {
                lineNumber++;
                int *positions = FindPositionOfSubString(line, wordToFind);
                if (found == 1)
                {
                    F = 1;
                    for (int  i = 0; i < sizeOfPositions; i++)
                    {
                        cout<<lineNumber<<":"<<positions[i]<<endl;
                    }
                    sizeOfPositions = 0;
                    delete positions;
                    found = 0;
                }
            }
            if (F == 0)
            {
                cout<<wordToFind<<" is not in file "<<fileName<<endl;
            }
            file.close();
        }
        else
        {
            cout<<"Not able to find "<<fileName<<endl;
        }
        cout<<endl<<"============================================================================="<<endl;
        getch();
    }
    return 0;
}



No comments

Powered by Blogger.