Sunday, July 16, 2017

Deletion and Updates

It has been quiet around here for almost 2 weeks, hasn't it? Then all of a sudden a new blog post is being uploaded and another deleted? What is going on? For one thing I didn't change any of my policies, for instance never change code once it has been submitted. Only in the case where there are bugs, or the code is in other ways being found to be faulty. So far it wasn't necessary to remove any code, and there is always a first, and this is the first case this has happened. 

The previous code for Programming Challenge 12.11 contained an error of sorts, or design-flaw rather. I sought help in a Coding community and received plenty of it. I got more help than I could ever have hoped for actually. In the beginning there was I and there was my code, I posted some snippets, of which I thought worked very well. In the following discussion I learned that I should not use a char array for division names but instead string class objects. This then led to lots of headaches on my part as I tried figuring out how to get a string in a struct into a binary file. 

I tried hard, asked many questions, and eventually managed to make things work. But instead of the fruits of all my labor in the past couple of days all you are getting to see is what seems like code containing minor changes? No fair! Of course it wouldn't be fair if I wouldn't share it with you. Here it is then, free for you to download and enjoy in all its sad glory. 

Example Files: CppSData.cpp
                         Xtra.dat

Of course you might think, why has this person not uploaded this code, and instead decided to upload another code as the solution to the Programming Challenge? To be honest with you? Doubts. While indeed the above code works, and I tested it numerous times, I still doubt that I should go with it until I learn way more about things. Until then I stick with what I know and can predict, which is reflected in the code I uploaded as solution. This will stay online as long as this blog will be live. (So, hopefully for eternity and a day ;-))

With this, I think, I will call it a day, and work hard to (finally) solve the next Programming Challenge. As always I would like to thank my visitors old and new, from all over the world, thank you for dropping by! I hope you found what you came looking for. Also many thanks for all the +s! My fellow learners I wish that you have a pleasant summer, and temperatures in a range allowing you to solve your own programming challenges without your brain melting. I hate the thought that I be learning alongside one of these:

Picture Copyright: PopCap Games


Programming Challenge 12.11 - Corporate Sales Data Output

Example File: IshikawaSalesData.dat


/* Corporate Sales Data Output - This program uses a structure to store
    the following data on a company division:

        * Division Name: East, West, North, South
        * Quarter: 1, 2, 3, 4
        * Quarterly Sales

    The user is asked for the four quarters' sales figures for the East,
    West, North and South divisions. The data for each quarter for each
    division is written to a file.

    Input Validation: No negative numbers for sales figures are accepted. */

#include "Utility.h"

const int NAME_SIZE = 15;
const int NUM_BRANCHES = 4;
const int NUM_QUARTERS = 4;

struct CorporateSales
{
    char divisionName[NAME_SIZE];                            /* Holds the division names */
    array<double, NUM_BRANCHES> quarterlySales;        /* Array to hold the quarterly sales figures*/
};

struct DivisionSales
{
    CorporateSales sales[NUM_BRANCHES];

    /* Initializer list */
    DivisionSales() : sales{ { "North Branch", { 0.0 } }, { "South Branch", { 0.0 } },
                                     { "East Branch",     { 0.0 } }, { "West Branch",  { 0.0} } } {}
};

void getSalesData(DivisionSales &);
int  writeData(DivisionSales &);

int main()
{
    DivisionSales division;

    getSalesData(division);
    writeData(division);

   pauseSystem();
   return 0;
}

/* **********************************************************
   Definition: getSalesData

    This function uses a reference parameter to a structure as
    its argument. The user is asked to enter quarterly sales
    figures for the four branches of a company. This data is
    stored in the appropriate structure member variables.
   ********************************************************** */

void getSalesData(DivisionSales &division)
{
    cout << "\n\tISHIKAWA FRUIT COMPANY - SALES DATA SYSTEM\n\n";
         
    for (int index = 0; index < NUM_BRANCHES; index++)
    {
        cout << "\n\tEnter Sales Data for " << division.sales[index].divisionName << ":\n";
        for (int qtrs = 0; qtrs < NUM_QUARTERS; qtrs++)
        {
            cout << "\tQuarter " << (qtrs + 1) << ":\t$ ";
            cin >> division.sales[index].quarterlySales[qtrs];

            while (division.sales[index].quarterlySales[qtrs] <= 0.0)
            {
                cout << "\tQuarter " << (qtrs + 1) << ":\t$ ";
                cin >> division.sales[index].quarterlySales[qtrs];
            }
        }
    }   
}

/* **********************************************************
   Definition: writeData

    This function uses a reference variable to a structure as
    its argument. The user is asked to enter a filename. Upon
    success, the CorporateSales structure data is written to
    to disk. In case of an error a message is displayed, and
    the program exits.
   ********************************************************** */

int writeData(DivisionSales &division)
{
    string fileName = "";

    cout << "\n\tEnter name of the file to output sales data to: ";
    cin >> fileName;

    fstream salesData(fileName.c_str(), ios::out | ios::binary);

    if (!salesData.fail())
    {
        cout << "\n\tWriting " << fileName << " to disk ...\n";

        salesData.write(reinterpret_cast<const char *>(&division),
                             sizeof(CorporateSales) * NUM_BRANCHES);

        cout << "\n\tData successfully written to " << fileName << "\n"
              << "\tNow closing the program ...\n\n"
              << "\tISHIKAWA FRUIT COMPANY - Your number one fruits supplier!";
    }
    else
    {
        cout << "\n\tFile Write Error! Could not write to " << fileName << "\n"
              << "\tPlease close this program and try again ...";
        return -1;
    }
    salesData.close();

    return 0;
}

Example Output:




Tuesday, July 4, 2017

Programming Challenge 12.10 - File Decryption Filter

Example Files: encrypted.txt
                          decrypted.txt


/* File Decryption Filter - This program decrypts the file produced by the
    program in Programming Challenge 12.9. It reads the contents of the coded
    file, restores the data to its original state, and writes it to another
    file. */

#include "Utility.h"

int    readFile(fstream &, string &);
string decryptText(string);
int    writeFile(fstream &, const string);

int main()
{
    fstream textFile;
    fstream textDecrypt;

    int    fOpen = 0;
    string cryptedText = "";
    string decrypted = "";

    cout << "File Decryption Filter\n\n";

    fOpen = readFile(textFile, cryptedText);

    if (fOpen != -1)
    {
        cout << "\nYour file will be decrypted now ...\n";
        decrypted = decryptText(cryptedText);

        cout << "File decrypted. Writing decrypted text to file ...\n";
        fOpen = writeFile(textDecrypt, decrypted);

        if (fOpen != -1)
        {
            cout << "\nFile successfully created. You can now close this program.\n"
                  << "Have a nice day!";
        }
    }

   pauseSystem();
   return 0;
}

/* **********************************************************
    Definition: readFile

    This function uses a reference parameter to an fstream
    object and a reference to a string object as parameters.
    Upon success, the contents of the file is read-in and
    stored in a string object.
   ********************************************************** */

int readFile(fstream &textFile, string &clearText)
{
    string fileName = "";
    string tmpText = " ";

    cout << "Enter name of file you wish to open: ";
    cin >> fileName;

    textFile.open(fileName, ios::in);

    if (!textFile.fail())
    {
        while (getline(textFile, tmpText))
        {
            clearText += tmpText;
        }
    }
    else
    {
        cout << "\nFile Read Error. Could not read " << fileName;
        return -1;
    }

    return 0;
}

/* **********************************************************
    Definition: decryptText

    This function uses a string object as its parameter. The
    contents in the string object is decrypted, and the string
    returned.
   ********************************************************** */

string decryptText(string decrypted)
{
    int basEnc = 0;
    int locEnc = 0;
    int locFin = 0;
    int locTxt = 0;

    basEnc = 32 / 3;
    locEnc = (5 + (basEnc + 5) * (basEnc + basEnc / 8));
    locFin = ((3 * basEnc) + (locEnc - 6));
    locTxt = ((1 - (basEnc + locEnc) * (basEnc + locEnc)) + locFin);

    for (int i = 0; i < decrypted.size(); i++)
    {
        decrypted[i] -= locTxt + locFin / locEnc;
    }

    return decrypted;
}

/* **********************************************************
    Definition: writeFile

    This uses a reference to an fstream object and a constant
    string object variable as parameters. Upon success, the
    file is opened, and the encrypted text contained in the
    string object is written to it.
   ********************************************************** */

int writeFile(fstream &cryptText, const string decrypted)
{
    string fileName = "";
    string tmpText = "";

    cout << "\nEnter name of file you wish to write to: ";
    cin >> fileName;

    cryptText.open(fileName, ios::out);
  
    if (!cryptText.fail())
    {  
        cryptText << decrypted << "\n";
    }
    else
    {
        cout << "File Write Error. Could not write data to " << fileName;
        return -1;
    }
    cryptText.close();

    return 0;
}

Example Output:



Programming Challenge 12.9 - File Encryption Filter

Example Files: long.txt
                          encrypted.txt


/* File Encryption Filter - File encryption is the science of writing the
    contents of a file in secret code. This encryption program works like
    a filter, reading the contents of one file, modifying the data into a
    code, and then writing the coded contents out to a second file. The
    second file is a version of the first file, but written in secret code. */

#include "Utility.h"

int  readFile(fstream &, string &);
string encryptText(string);
int writeFile(fstream &, const string);

int main()
{
    fstream textFile;
    fstream textCrypt;

    int    fOpen = 0;
    string clearText = "";
    string encrypted = "";

    cout << "File Encryption Filter\n\n";

    fOpen = readFile(textFile, clearText);

    if (fOpen != -1)
    {
        cout << "\nYour file will be encrypted now ...\n";
        encrypted = encryptText(clearText);

        cout << "File encrypted. Writing encrypted text to file ...\n";
        writeFile(textCrypt, encrypted);

        if (fOpen != -1)
        {
            cout << "\nFile successfully created. You can now close this program.\n"
                  << "Have a nice day!";
        }
    }

   pauseSystem();
   return 0;
}

/* **********************************************************
    Definition: readFile

    This function uses a reference parameter to an fstream
    object and a reference to a string object as parameters.
    Upon success, the contents of the file is read-in and
    stored in a string object.
   ********************************************************** */

int readFile(fstream &textFile, string &clearText)
{
    string fileName = "";
    string tmpText = " ";

    cout << "Enter name of file you wish to open: ";
    cin >> fileName;

    textFile.open(fileName, ios::in);

    if (!textFile.fail())
    {
        while (getline(textFile, tmpText))
        {
            clearText += tmpText + " ";
        }
    }
    else
    {
        cout << "\nFile Read Error. Could not read " << fileName;
        return -1;
    }
    textFile.close();

    return 0;
}

/* **********************************************************
    Definition: encryptText

    This function uses a string object as parameters. The
    contents in the string object is encrypted, and the string
    returned.
   ********************************************************** */

string encryptText(string encrypted)
{
    int basEnc = 0;
    int locEnc = 0;
    int locFin = 0;
    int locTxt = 0;

    basEnc = 32 / 3;
    locEnc = (5 + (basEnc + 5) * (basEnc + basEnc / 8));
    locFin = ((3 * basEnc) + (locEnc - 6));
    locTxt = ((1 - (basEnc + locEnc) * (basEnc + locEnc)) + locFin);

    for (int i = 0; i < encrypted.size(); i++)
    {
        encrypted[i] += locTxt + locFin / locEnc;       
    }

    return encrypted;
}

/* **********************************************************
    Definition: writeFile

    This uses a reference to an fstream object and a constant
    string object variable as parameters. Upon success, the
    file is opened, and the encrypted text contained in the
    string object is written to it.
   ********************************************************** */

int writeFile(fstream &cryptText, const string encrypted)
{
    string fileName = "";

    cout << "\nEnter name of file you wish to write to: ";
    cin >> fileName;

    cryptText.open(fileName, ios::out);
   
    if (!cryptText.fail())
    {   
        cryptText << encrypted;
    }
    else
    {
        cout << "File Write Error. Could not write data to " << fileName;
        return -1;
    }
    cryptText.close();

    return 0;
}

Example Output:




Monday, July 3, 2017

Programming Challenge 12.8 - Array/File Functions

/* Array/File Functions - This program contains a function named arrayToFile.
    It accepts three arguments:
   
        * The name of a file
        * A pointer to an int array
        * The size of the array

    The function opens the specified file in binary mode, writes the contents
    of the array to the file, and the closes the file.

    It also contains another function named fileToArray. This functions accepts
    three arguments:

        * The name of a file
        * A pointer to an int array
        * The size of the array

    The function opens the specified file in binary mode, reads its contents
    into the array, and then closes the file.

    The functions are demonstrated in this program, by using the arrayToFile
    function to write an array to a file, and then using the fileToArray function
    to read the data from the same file. After the data are read from the file
    into the array, the array's contents are displayed on the screen. */

#include "Utility.h"

void rNumGenerator(int *, const int);
int  arrayToFile(const string fileName, int *, const int);
int  fileToArray(const string fileName, int *, const int);
void displayArray(const int *, const int);

int main()
{
    const int NUMELS = 6;

    int     lotteryNumbers[NUMELS] = { 0 };
    int     fOpenErr = 0;
    string fileName = "";

    cout << "ARRAY/FILE FUNCTIONS.\n\n"
          << "This program demonstrates two functions. One writes an array\n"
          << "containing RNG-numbers to a file in binary mode, the other reads\n"
          << "the contents of the file into an array. If both operations are\n"
          << "successful, the contents of the array is displayed.\n\n";

    cout << "Enter the name of a file to write to: ";
    cin >> fileName;

    fOpenErr = arrayToFile(fileName, lotteryNumbers, NUMELS);

    if (fOpenErr != -1)
    {
        cout << "Enter the name of a file to read from: ";
        cin >> fileName;

        fileToArray(fileName, lotteryNumbers, NUMELS);
    }

   pauseSystem();
   return 0;
}

/* **********************************************************
   Definition: rNumGenerator

    This function accepts a pointer to an array and its size
    as parameters. It fills the array with 6 random numbers.
   ********************************************************** */

void rNumGenerator(int *lotteryNums, const int NUMELS)
{
    const int HIGHEST_NUM = 45,
               LOWEST_NUM = 1;

    int lastNum = 0;
    int count = 0;
   
    srand((unsigned int)time(0));

    while (count < NUMELS)
    {
        lastNum = (rand() % (HIGHEST_NUM - LOWEST_NUM + 1) + LOWEST_NUM);
       
        if (lastNum != 0)
        {
            *(lotteryNums + count) = lastNum;
        }

        count++;
    }
}

/* **********************************************************
   Definition: arrayToFile

    This functions accepts the name of a file, a pointer to an
    integer array, and the size of the array as parameters. It
    opens the file in binary mode, writes the contents of the
    array to the file, and the closes the file.
   ********************************************************** */

int arrayToFile(const string fileName, int *lotteryNums, const int NUMELS)
{
    char *arrPtr = nullptr;

    rNumGenerator(lotteryNums, NUMELS);

    fstream toFile(fileName, ios::out | ios::binary);

    if (!toFile.fail())
    {

        cout << "\nWriting array data to file ...\n";
        toFile.write(reinterpret_cast<char *>(lotteryNums), sizeof(lotteryNums));
        cout << "Array contents successfully written to file.\n"
              << "Now closing " << fileName << "\n\n";
    }
    else
    {
        cout << "\nFile Writing Error. Array contents could not be written to file ...\n"
              << "Press enter to close this program.";
        return -1;
    }
    toFile.close();

    return 0;
}

/* **********************************************************
   Definition: fileToArray

    This functions accepts the name of a file, a pointer to an
    integer array, and the size of the array as parameters. It
    opens the file in binary mode, reads its contents into the
    array, and then closes the file.
   ********************************************************** */

int fileToArray(const string fileName, int *lotteryNums, const int NUMELS)
{
    char *arrPtr = nullptr;

    fstream fromFile(fileName, ios::binary | ios::in);
   
    if (!fromFile.fail())
    {
        cout << "\nReading in file-contents ...\n";
        fromFile.read(reinterpret_cast<char *>(lotteryNums), sizeof(lotteryNums));
        cout << "File contents successfully read into array.\n"
              << "Now closing " << fileName << "\n\n";

        cout << "\nThis is the array's contents: ";
        displayArray(lotteryNums, NUMELS);
    }
    else
    {
        cout << "File Reading Error. Could not read " << fileName << " ...";
        return -1;
    }
    fromFile.close();

    return 0;
}

/* **********************************************************
   Definition: displayArray

    This functions accepts a constant pointer to an integer
    array, and the size of the array as parameters. It outputs
    the contents of the array to screen.
   ********************************************************** */

void displayArray(const int *lotteryNums, const int NUMELS)
{
    for (int i = 0; i < NUMELS; i++)
    {
        cout << *(lotteryNums + i) << " ";
    }
}

Example Output:






Programming Challenge 12.7 - Sentence Filter

Example Files: capitalizer.txt
                         capitalized.txt


/* Sentence Filter - This program asks the user for two file names. The
    first is opened for input and the second file is opened for output.
    (It is assumed that the first file contains sentences that end with
    a period.) The program reads the contents of the first file and changes
    all the letters to lowercase except the first letter of each sentence,
    which is made uppercase. The revised contents is stored in the second
    file. */

#include "Utility.h"

int  fileIO();
void senDecapitalizer(string &);
void wordCapitalizer(string &);


int main()
{
    cout << "SENTENCE FILTER\n\n";

    fileIO();

   pauseSystem();
   return 0;
}

/* **********************************************************
   Definition: fileIO

    This function first attempts to open and read-in text from
    a file. Upon success, the text is processed, and the file
    is closed. Another file is opened for output. If the file
    is created successfully, the processed text is output to
    the file. If one or both file operations fail, an error
    message is displayed, and the program exits.
   ********************************************************** */

int fileIO()
{
    string tmpText = "";
    string sentence = "";

    fstream readFrom;
    fstream writeTo;

    readFrom.open("capitalizer.txt", ios::in);

    if (!readFrom.fail())
    {
        cout << "Reading in contents of text file ...";

        while (getline(readFrom, tmpText))
        {       
            senDecapitalizer(tmpText);
            wordCapitalizer(sentence);

            sentence += tmpText + "\n";
        }
        cout << "\nFile successfully processed.\n\n";
    }
    else
    {
        cout << "File open error. Now exiting the program ...";
        return -1;
    }
    readFrom.close();
   
    cout << "Now closing the file ..\n";

    /* Write data to the file */
    writeTo.open("capitalized.txt", ios::out);

    if (!writeTo.fail())
    {
        cout << "\nWriting text to the file ...";
        writeTo << sentence << " ";

        cout << "\nText successfully written to file.\n";
    }
    else
    {
        cout << "\nFile Writing Error. Unable to create or process file ...\n"
              << "Press enter to exit this program.";
        return -1;
    }
    writeTo.close();

    cout << "\nPress enter to close this program ...";

    return 0;
}

/* **********************************************************
   Definition: senDecapitalizer

   This function accepts a reference to a string object as
    its parameter. It replaces all uppercase characters found
    in a sentence by their lowercase equivalent.
   ********************************************************** */

void senDecapitalizer(string &sentence)
{
    for (unsigned int index = 0; index < sentence.length(); index++)
    {
        if (isupper(sentence[index]))
        {
            sentence[index] = tolower(sentence[index]);
        }
    }
}

/* **********************************************************
   Definition: wordCapitalizer

    This function accepts a reference to a string object as
    its parameter. It turns all letters found at the beginning
    of a sentence to uppercase.
   ********************************************************** */

void wordCapitalizer(string &sentence)
{
    bool isDelim = false;

    for (unsigned int index = 0; index < sentence.length(); index++)
    {
        if (sentence.at(index) == '.' || sentence.at(index) == '!' ||
            sentence.at(index) == '?' || sentence.at(index) == ';')
        {
            isDelim = false;
        }

        if (isalpha(sentence.at(index)) && isDelim == false)
        {
            isDelim = true;
            sentence.at(index) = toupper(sentence.at(index));
        }
    }
}

Example Output:




Sunday, July 2, 2017

Programming Challenge 12.6 - String Search

Example-File: short.txt
Include-File: UtilityCls.h


/* String Search - This program asks the user for a file name and a string
    to search for. The program searches the file for every occurrence of a
    specified string. When the string is found, the line that contains it is
    displayed. After all the occurrences have been located, the program reports
    the number of times the string appeared in the file. */

#include "UtilityCls.h"

struct GetFile
{
    string fileName;        /* The file name    */
    fstream textFile;        /* fstream object */

    GetFile(string fName = "")
    {
        fileName = fName;
    }

    ~GetFile()
    {
    }
};

struct TextSearch
{
    int    timesFound;        /* Counts the occurrences of words found in the text        */
    string searchWord;        /* Holds the word to search for in the text                    */
    string delimList;            /* Holds a list of delimiting characters                        */
    string tmpText;            /* A temporary variable to hold text while it is read in */
    string getText;            /* Holds the text read in from the file                        */
    string searchResult;        /* Holds the search result                                            */

    TextSearch(int cnt = 0, string dlmLst = ".:)(!?\";,", string sw = " ",
                string gTxt = " ", string sRes = " ")
    {
        timesFound = cnt;
        searchWord = sw;
        delimList = dlmLst;
        getText = gTxt;
        searchResult = sRes;
    }

    ~TextSearch()
    {
    }
};

void menu(GetFile &, TextSearch &);
char tryAgain();
void getFileName(GetFile &);
int  openFile(GetFile &, TextSearch &);
void getSearchWord(TextSearch &);
void changeCase(TextSearch &);
void removePunct(TextSearch &);
void performTextSearch(TextSearch &, const string);
void getWordFreq(TextSearch &);
void displayResult(const TextSearch &);
void cleanUp(GetFile &, TextSearch &);

int main()
{
    GetFile fileData;
    TextSearch search;
   
    menu(fileData, search);

    pauseSystem();
    return 0;
}

/* **********************************************************
    Definition: menu

    This function uses a two structure reference parameters.
    It offers a basic menu and introduction to the program.
    ********************************************************** */

void menu(GetFile &fileData, TextSearch &search)
{
    int  fOpen = 0;
    char again = ' ';

    cout << "\n\tText Search\n\n"
          << "\tThis program allows you to search for a word\n"
          << "\tin any given text-file. It will only find whole\n"
          << "\twords. To give you an example, if you type in the\n"
          << "\tword 'is', it will only find and display this word\n"
          << "\tand sentences that contain it. If 'is' is part of\n"
          << "\tanother word, like 'this', it will not be found.\n\n";

    do
    {
        fOpen = openFile(fileData, search);

        if (fOpen != -1)
        {
            cout << "\n\n\tText Search - Search Result\n\n";
            displayResult(search);
        }

        again = tryAgain();

        if (again == 'N')
        {
            cout << "\n\tThank you for trying this program!";
        }
        else
        {
            clearScreen();
            cleanUp(fileData, search);
        }
    } while (again != 'N');
}

/* **********************************************************
    Definition: openFile

    This function uses a two structure reference parameters as
    its arguments. First, the user is asked to enter a file
    name. If the file exists and is opened successfully, the
    user is asked to enter a word to search for. Then the file
    contents is read in and processed by other functions,
    while the text is being read-in. In case of an error, an
    error message is displayed, and the function exits.
    ********************************************************** */

int openFile(GetFile &fileData, TextSearch &search)
{
    string tmpText = "";

    getFileName(fileData);

    while (fileData.fileName.empty())
    {
        cin >> fileData.fileName;
    }

    /* Open the file for reading */
    fileData.textFile.open(fileData.fileName, ios::in);

    if (!fileData.textFile.fail())
    {
        getSearchWord(search);

            while (getline(fileData.textFile, tmpText))
            {       
                search.getText = ' ' + tmpText + ' ';

                removePunct(search);
                changeCase(search);
                performTextSearch(search, tmpText);
                getWordFreq(search);
            }
    }
    else
    {
        cout << "\tFile open error: " << fileData.fileName
              << " could not be openend.";
        return -1;
    }
    fileData.textFile.close();

    return 0;
}

/* **********************************************************
    Definition: getSearchWord

    This function uses a structure reference parameter. The
    user is asked to enter a word to search for. If the word
    contains uppercase letters, they are changed to lowercase.
    This allows to search for 'Pac-man' as well as 'pAc-Man'
    or any other variation of casing letters.
    ********************************************************** */

void getSearchWord(TextSearch &search)
{
    cout << "\tPlease enter a word to search for: ";
    cin >> search.searchWord;

    while (search.searchWord.empty() || search.searchWord == "\0")
    {
        cout << "\tPlease enter a word to search for: ";
        cin >> search.searchWord;
    }

    for (size_t i = 0; i < search.searchWord.size(); i++)
    if (isupper(search.searchWord.at(i)))
    {
        search.searchWord.at(i) = tolower(search.searchWord.at(i));
    }
}

/* **********************************************************
    Definition: getFileName

    This function uses a structure reference as parameter. It
    asks the user for a filename. If the filename does not
    contain a file-extension, for example '.txt', it is added,
    and the filename stored in a struct member variable. If a
    file-extension has been entered, the filename is stored,
    and the function exits.
    ********************************************************** */

void getFileName(GetFile &getName)
{
    string fileExt = ".txt";

    cout << "\n\tPlease enter a file name: ";
    cin >> getName.fileName;

    if (getName.fileName.find(".") != string::npos)
    {
        getName.fileName;
    }
    else
    {
        getName.fileName.append(fileExt);
    }
}
/* **********************************************************
    Definition: changeCase

    This function uses a structure reference parameter. It
    turns all uppercase letters found in a text to lowercase.
    ********************************************************** */

void changeCase(TextSearch &search)
{
    for (int i = 0; i < search.getText.size(); i++)
    {
        search.getText[i] = tolower(search.getText[i]);
    }
}

/* **********************************************************
    Definition: removePunct

    This function uses a structure reference parameter. It
    finds and removes selected punctuation characters. Once
    done, the text stored in a structure member variable.
    ********************************************************** */

void removePunct(TextSearch &search)
{
    for (int i = 0; i < search.delimList.size(); i++)
    {
        search.getText.erase(remove(search.getText.begin(), search.getText.end(),
                                             search.delimList.at(i)), search.getText.end());
    }
}

/* **********************************************************
    Definition: performTextSearch

    This function uses a structure reference parameter and a
    string object holding the unprocessesed text. It searches
    for the occurence of the word. If a match is found, the
    sentence(s) containing it are stored in the appropriate
    structure member variable.
    ********************************************************** */

void performTextSearch(TextSearch &search, const string tmpText)
{
    if (search.getText.find(' ' + search.searchWord + ' ') != string::npos)
    {
        search.searchResult.append("\t" + tmpText + "\n");
    }
}

/* **********************************************************
    Definition: getWordFreq

    This function uses a structure reference variable as its
    argument. It contains a stringstream object, which, word
    by word, extracts the text from a struct member variable
    holding the full text. It searches for an occurence of the
    word input by the user. If a match is found, a counter,
    which is another struct member variable, increments.
    ********************************************************** */

void getWordFreq(TextSearch &search)
{
    stringstream ss(search.getText);

    while (ss >> search.getText)
    {
        if (search.getText == search.searchWord)
        {
            ++(search.timesFound);
        }
    }
}

/* **********************************************************
    Definition: displayResult

    This function uses a constant structure reference variable
    as its argument. If the word to be searched for has been
    found, the word, the sentence(s) contaninig this word, and
    the number of matches is displayed. If there is no match,
    the user is informed by a message about the fact.
    ********************************************************** */

void displayResult(const TextSearch &search)
{
    if (search.timesFound != 0)
    {
        cout << "\n\tYour search word: " << search.searchWord << " was found "
            << search.timesFound << " times.\n";

        cout << "\n\tThe following sentence(s) contain this word:\n\n"
            << search.searchResult;
    }
    else
    {
        cout << "\n\tNo match found for your search word: " << search.searchWord;
    }
}

/* **********************************************************
    Definition: tryAgain

    This function asks the user if he or she wishes to try
    again. This decision is returned.
    ********************************************************** */

char tryAgain()
{
    char again = ' ';

    cout << "\n\n\tDo you wish to perform another search? ";
    cin >> again;
    cin.ignore();

    /* Input validation */
    while (toupper(again) != 'Y' && toupper(again) != 'N')
    {
        cout << "\n\tDo you wish to perform another search? ";
        cin >> again;
        cin.ignore();
    }

    return toupper(again);
}

/* **********************************************************
    Definition: cleanUp

    This function uses two structure reference parameters. It
    clears any content present in the struct member variables.
    This is necessary to be able to perform another search
    without exiting the program.
    ********************************************************** */

void cleanUp(GetFile &clean, TextSearch &search)
{
    clean.fileName.clear();
    clean.textFile.clear();
    search.getText.clear();
    search.timesFound = 0;
    search.searchWord.clear();
    search.searchResult.clear();
}

Example Output: