I've got the following program, a header file, .cpp file, and p2.cpp, and it does not run correctly. It works when typing in a text document, but after that, it does not read the file how I want it to. I used the cout statements in main of p2.cpp to see when exactly it crashes, it cout'd the statements until it got to readFile, then it crashes. Here's all the code.
Header:

//File WordList.h
//Definition of class WordList
#ifndef WORDLIST_H
#define WORDLIST_H
#include <iostream>
#include <string>
#include <iomanip>
#include <fstream>

using namespace std;

//max capacity of Words array
int const CAPACITY=1000;

struct WordRec
{
  string Word;         //Words in Array of struct
  int wordNum;           //Word count in array of struct
};

class WordList
{
 public:

  //WordList Contructor
  WordList();

  //Get
  //Returns number of words
  int getNumWords() const;

  // gets the word
  string getWord(int indx);

  //Other member functions
  WordRec &operator[](const int indx);
  const WordRec &operator[](const int indx) const;

  //Puts words from file into array
//  void addWord(string words);  
  const void operator+=(string word);

  //Returns a boolean value to determine whether the array has reached capacity
  bool full();

  void arrange();

 private:

  // The Data...
  //Instance of struct
  WordRec Words[CAPACITY];   
  //Number of elements in the array of struct
  int numWords;

  //the index
  int indx;

  // Private Member Functions...
  //Funtion for incrementing elts
  void incNumWords();

  //Function for decrementing number of words
  void decNumWords(int amt);

  void incWordCount(int indx);

  //Function for placing a word into List array
  void setWord(int indx, string word);

  //  Set Count to 0
  void initCount();

  //Swap for sort()
  void swap (int num1, int num2);

  //Sort function for sorting array of struct
  void sort();

  //Function to remove duplicates from array of struct
  void removeDups();            

};

bool operator<(const WordRec &left,const WordRec &right);

ostream &operator<<(ostream &out,const WordRec &WR);
ostream &operator<<(ostream &out,const WordList &WL);

#endif

.cpp

#include <iostream>
#include <fstream>
#include "WordList.h"
#include <iomanip>
#include <string>

using namespace std;

/******************
Function: WordList

Description: constructor, initializes count to 0

Parameters: None

Return Value: none
******************/
WordList::WordList()
{
    initCount();
}

/****************************
Function: initCount

Description: sets numWords to 0

Parameters: none

Return Value: none
****************************/
void WordList::initCount()
{
    numWords = 0;
}

/****************************
Function: setWord

Description: sets the word in that specific index to be string word

Parameters: int indx - IMPORT - the index in the array where the word is going
            string word - IMPORT - the word that is being moved into the array

Return Value: none
***************************/
void WordList::setWord(int indx, string word)
{
    Words[indx].Word = word;
}

/****************************
Function: getWord

Description: gets the word for that specific index

Parameters: int indx - IMPORT - the index in the array where the word you want is

Return Value: the string of Words[indx].Word
***************************/
string WordList::getWord(int indx)
{
    return Words[indx].Word;
}

/****************************
Function: getNumWords

Description: retuns

Parameters: 

Return Value: the int number in numWords
***************************/
int WordList::getNumWords() const
{
    return numWords;
}

/****************************
Function: incWordCount

Description: increases the value of the amount of that word in the array

Parameters: int indx - IMPORT - the index in the array where you're increasing the wordNum

Return Value: none
***************************/
void WordList::incWordCount(int indx)
{
    Words[indx].wordNum++;
}

/****************************
Function: full

Description: checks to see if numWords is still under 1000, returns false if it is

Parameters: 

Return Value: true or false depending on amount in numWords
***************************/
bool WordList::full()
{
    return (numWords >= 1000);
}

/****************************
Function: decNumWords

Description: decrements the number of words by the amount given

Parameters: int amt - IMPORT - the amount you wish to decrement numWords by

Return Value: none
***************************/
void WordList::decNumWords(int amt)
{
    numWords -= amt;
}

/****************************
Function: incNumWords

Description: increments number of words by 1

Parameters: 

Return Value: none
***************************/
void WordList::incNumWords()
{
    numWords++;
}

/****************************
Function: swap

Description: Swaps the index of one part of Words with another part. Also swaps the word amount. Used to change word order.

Parameters: num1 - IMPORT - Used to hold the value of the first index in the array that is being swapped.
            num2 - IMPORT - Holds the second value of the other index in the array being swapped.
            temp - Temporarily holds the word in Words[swapNum1].Word while it is being swapped.
            numtemp - Temporarily holds the word amount in Words[swapNum1].WordAmt while it's being swapped.

Return Value: None
***************************/
 void WordList::swap(int num1, int num2)
 {
    string temp;
    int numtemp;

    temp = Words[num1].Word;
    Words[num1].Word = Words[num2].Word;
    Words[num2].Word = temp;

    numtemp = Words[num1].wordNum;
    Words[num1].wordNum = Words[num2].wordNum;
    Words[num2].wordNum = numtemp;

     return;
 }

 /****************************
Function: sort

Description: Sorts the array of Words into alphabetical order, A-Z, or, left to right. 

Parameters: 

Return Value: None
***************************/
void WordList::sort()
{
    for (int spot = 0; spot < numWords - 1; spot++)
    {
        int minIndex = spot;
        for (int index = spot + 1; index < numWords; index++)
        {
            if (Words[index].Word < Words[minIndex].Word)
            {
                minIndex = index;
            }
        }
        if (minIndex != spot)
        {
            swap(minIndex, spot);
        }
    }
}

/****************************
Function: removeDups

Description: Finds duplicate words in the struct, removes them, and adds 1 to the word amount of that word.

Parameters: 

Return Value: None
****************************/
void WordList::removeDups()
{
    for (int spot = 0; spot < numWords - 1; spot++)
    {
        int minIndex = spot;
        if (spot > 0 && Words[spot].Word == Words[spot - 1].Word)
        {
            incWordCount(spot);

            swap(numWords - 1, spot);

            decNumWords(1);
            spot--;
        }
    }
}

/****************************
Function: arrange

Description: Calls sort and removeDups for easier usage.

Parameters: 

Return Value: None
****************************/
void WordList::arrange()
{
    sort();
    removeDups();
}

/****************************
Function: operator<

Description: Overloads the less than operator. Returns true or false depending on if the word on the left is less than the word on 
the right

Parameters: WordRec &left - IMPORT - the WordRec on the left being compared
            WordRec &right - IMPORT - the WordRec on the right

Return Value: true or false depending on result.
****************************/
bool operator<(const WordRec &left, const WordRec &right)
{
    return (left.Word < right.Word);
}

/****************************
Function: operator<<

Description: operator overload of <<. outputs a specific word and wordNum.

Parameters: out - IMPORT/EXPORT? - how you're printing out to the screen?
            WR - IMPORT - to get access to the word and wordNum you're outputting

Return Value: out
****************************/
ostream &operator<< (ostream &out, const WordRec &WR)
{
    cout << setw(15) << WR.Word << setw(15) << WR.wordNum <<endl;
    return(out);
}

/****************************
Function: operator<<

Description: operator overload of <<. outputs all words in WL

Parameters: out - IMPORT/EXPORT? - how you're printing out to the screen?
            WL - IMPORT - to get access to the word and wordNum you're outputting

Return Value: out
****************************/
ostream &operator<<(ostream &out,const WordList &WL)
{
   cout << "All words in the file:\n\n";
   cout << setw(15) << "Words" << setw(15) << "Count" << endl;
   int indx = 0;
   while(indx != WL.getNumWords())
     { 
        out << WL[indx] << endl;
        indx++;
     }
   return(out);
}

/****************************
Function: operator+=

Description: operator overload of +=. Deals with taking in the word, setting it, incrementing the count
in that index, incrementing the number of words, and then incrementing the index.

Parameters: string word - IMPORT/EXPORT? - the word you're placing into the array

Return Value: none
****************************/
const void WordList::operator+=(string word)
{
    setWord(indx, word);
    incWordCount(indx);
    incNumWords();
    indx++;
}

/****************************
Function: operator[]

Description: operator overload of []

Parameters: int indx - IMPORT - the index of Words

Return Value: Words[indx]
****************************/
WordRec &WordList::operator[](int indx)
{ 
    return (Words[indx]);
}

/****************************
Function: operator[]

Description: operator overload of [], constant

Parameters: int indx - IMPORT - the index of Words

Return Value: Words[indx]
****************************/
const WordRec &WordList::operator[](int indx) const
{ 
    return (Words[indx]);
}

p2.cpp

/************************************************
/Name: Zachary Bryan
/Course: CS136 020
/Assignment: Project 1
/Due Date: October 5th, 2012
/Files: p2.cpp, WordList.h, WordList.cpp, makefile
/Purpose: The program will open a file that the user tells it to open, and will output the characters, lines,
/and order the words from A to Z, eliminating duplicates and counting the amount of that word used in the process.
/It also outputs words with the amount of that word that the user requests. If the user puts in 0, it outputs everything.
*************************************************/

#include <iostream>
#include <string>
#include <fstream>
#include "WordList.h"

using namespace std;

void openFile(ifstream &filein, string &fileLocation);

void charCount(ifstream &filein, int& lineAmt, int& charAmt);

void reopenFile (ifstream &filein, string &fileLocation);

void readFile(ifstream &filein, WordList WL);

void strUpr(string &str);

void outputResults(string fileLocation, int charAmt, int lineAmt, WordList WL);


/****************************
Function: main

Description: Calls all the functions and initalizes the variables needed.

Parameters: WordList WL - IMPORT/EXPORT - Needed to call all functions that are public in WordList.cpp
            charAmt - EXPORT - holds the # of characters
            lineAmt - EXPORT - holds # of lines
            fileLocation - EXPORT - holds the string of the file's location
            filein - EXPORT - used when dealing with opening and closing file, also grabbing the words.

Return Value: None
***************************/
int main()
{
    WordList WL;
    int charAmt = 0, lineAmt = 0;
    string fileLocation;
    ifstream filein;
    WordRec WR;

    openFile(filein, fileLocation);
    cout << "It opens the file" << endl;

    charCount(filein, charAmt, lineAmt);
    cout << "It counts the chars and lines" << endl;

    reopenFile(filein, fileLocation);
    cout << "It reopens the file" << endl;

    readFile(filein, WL);
    cout << "It reads the file" << endl;

    outputResults(fileLocation, charAmt, lineAmt, WL);

    return 0;
}

/****************************
Function: openFile

Description: Opens the file entered in by the user. If the file couldn't be opened, 
it returns an error and asks for input again.

Parameters: ifstream filein - IMPORT/EXPORT - Deals with file tasks such as opening the file.
            string fileLocation - IMPORT/EXPORT - holds the string of the file location entered by the user.

Return Value: None
***************************/
void openFile(ifstream &filein, string &fileLocation)
{
    cout << "Hello again! This program will open a text file of your choosing, and then output the amount of characters and lines," 
        << "as well as output all words that appear the same amount of times as the number you input (Ex. All words that appear 3 times"
        << "will be shown when you enter 3)." << endl;
    do
    {
        cout << "Please enter the name of the file (Include .txt at the end of the file's name)." << endl;

        cin >> fileLocation;

        filein.open(fileLocation.c_str());
        if (filein.is_open() == true)
        {
            return;
        }
        else
        {
            cout << "Error: File not found." << endl;
        } 
    } while (filein.is_open() == false);
    return;
}

/****************************
Function: charCount

Description: Counts the amount of characters that are within the file.
Also counts the amount of new lines the file has.

Parameters: ifstream filein - IMPORT/EXPORT - Deals with file tasks of getting characters and lines from the file using .get()
            int lineAmt - IMPORT/EXPORT - Holds the amount of characters found within the file.
            int charAmt - IMPORT/EXPORT - Holds the amount of new lines found within the file.

Return Value: None
***************************/
void charCount(ifstream &filein, int& lineAmt, int& charAmt)
{
    do
    {
        if (filein.get() == '\n')
        {
            lineAmt++;
            charAmt++;
        }
        else
        {
            charAmt++;
        }
    } while (!filein.eof());

    lineAmt++;

    return;
}

/*****************************
Function: readFile

Description: Takes the words from the file and places them into string word, which is then converted into all uppercase
and then added into the array of struct WordRec.

Parameters: filein - IMPORT - places a word into word
            word - EXPORT - holds the word which is then placed into strUpr and then added into the array of struct WordRec
            WL - IMPORT/EXPORT - used for calling WL.full() and for the += operator.

Return Value: none
*****************************/
void readFile(ifstream &filein, WordList WL)
{
    string word;
    while (WL.full() == false && filein >> word)
    {
        strUpr(word);
        WL += word;
        cout << word;
    }
    WL.arrange();
    return;
}

/****************************
Function: reopenFile

Description: Closes the file, clears it, then re-opens it.

Parameters: ifstream filein - IMPORT/EXPORT - Deals with file tasks.
            string fileLocation - IMPORT/EXPORT - holds the string of the file location entered by the user.

Return Value: None
***************************/
void reopenFile(ifstream &filein, string &fileLocation)
{
    filein.close();
    filein.clear();
    filein.open(fileLocation.c_str());
    return;
}

/***********************
Function: strUpr

Description: Takes a string and converts it to all uppercase letters.

Parameters: str - IMPORT/EXPORT - holds the string

Return Value: none
***********************/
void strUpr(string &str)
{ 
    for (int indx = 0; indx < str.length(); indx++)
        str[indx] = toupper(str[indx]);
    return;
}

/****************************
Function: outputResults

Description: Outputs all information collected by the program, along with words that appear the amount of the times the user
wishes to see. If 0 entered, outputs all words. Exits when a negative number is input.

Parameters: string fileLocation - IMPORT - holds the name of the file opened.
            int charAmt - IMPORT - Holds the amount of characters founds within the file.
            int lineAmt - IMPORT - Holds the amount of lines in the file.
            WordList WL - IMPORT - Deals with all WordList tasks

Return Value: None
***************************/
void outputResults(string fileLocation, int charAmt, int lineAmt, WordList WL)
{
    int userChoice = 0;

    cout << charAmt << endl << lineAmt;
    while (userChoice >= 0)
    {
    cout << "Enter the number of how many times a word appears that you'd like to see output (Ex. enter 3 to see all words that appeared 3 times)" << endl
        << "Enter 0 to display all words and word counts, and enter a negative number to exit." << endl;
    cin >> userChoice;
    if (userChoice == 0)
    {
        cout << WL;
    }
    else
    {
        for (int j = 0; j < WL.getNumWords(); j++)
        {
            //would check to see if Words[j].wordAmt == userChoice, then output Words[j].word if so
        }
    }
    }
    return;
}

Edited 4 Years Ago by Secone

Lines 298-303 (wordlist.cpp), in method const void WordList::operator+=(string word) just check if the indx is within range.

// do we have space to add 1 more word?
if (indx + 1 < CAPACITY) {
    setWord(indx, word);
    incWordCount(indx);
    incNumWords();
    indx++;
}

Line 149 (p2.cpp) you have void readFile(ifstream &filein, WordList WL) which is probably not what you have. You want to pass the 'WL' by reference or pointer so add the reference operator & (..., WordList &WL);

One important thing when working with classes, make sure you initialize all your primitive data types int/long/char and pointers.

By looking at your constructor, you never initialized int indx; so when you try adding a word in line 155 (p2.cpp file) in function void readFile(ifstream &filein, WordList WL) with WL += word;. You can see that you're trying to use the variable 'indx' but you never properly initialized it, so it contains garbage data and your program crashes as a result.

Edited 4 Years Ago by dx9_programmer

This article has been dead for over six months. Start a new discussion instead.