Search code examples
c++classdictionarystlkeyvaluepair

how to read files using containers in STL


I have to read word by word from "testdata.txt"and look for the same words in another file "dictionary.txt". I already implemented the code to read the "dictionary.txt" in ReadDictionary() function. But I have to Implement the ReadTextFile() public member function in order to read the file named: “testdata.txt” into the “KnownWords” and “UnknownWords” data which are private members. Only “known” words should be put in the “KnownWords” and the rest to "UnknownWords". I have to use map and pair but i have no idea how to use it in my programming. Can someone please help me figure this one out in order to get this output:

89 known words read.
49 unknown words read.

int main():

WordStats ws;
ws.ReadTxtFile();

HeaderFile:

using namespace std;
typedef map<string, vector<int> > WordMap;     
typedef WordMap::iterator WordMapIter;        

class WordStats
{
public:
    WordStats();
    void ReadDictionary();
    void DisplayDictionary();
    void ReadTxtFile();
private:
    WordMap KnownWords;
    WordMap UnknownWords;
    set<string> Dictionary;
    char Filename[256];
};

This is my program:

WordStats::WordStats(){
strcpy(Filename,"testdata.txt");
}

// Reads dictionary.txt into Dictionary
void WordStats::ReadDictionary(){
    string word;    
    ifstream infile("dictionary.txt");
    if(!infile)
    {
        cerr << "Error Opening file 'dictionary.txt. " <<endl;
        exit(1);
    }
    while(getline(infile,word))
    {       
        transform (word.begin(), word.end(), word.begin(), ::tolower);
        Dictionary.insert(word); 
    }
    infile.close();
    cout << endl;
    cout << Dictionary.size() << " words read from dictionary. \n" <<endl;

}
// Reads textfile into KnownWords and UnknownWords
void WordStats::ReadTxtFile(){
    string words;
    vector<string> findword;
    vector<int> count;
    ifstream ifile(Filename);
    if(!ifile)
    {
        cerr << "Error Opening file 'dictionary.txt. " <<endl;
        exit(1);
    }
    while(!ifile.eof())
    {
        getline(ifile,words);
        //KnownWords.insert( pair<string,int>( KnownWords, words ) );
        findword.push_back(words);
        Paragraph = KnownWords.find(words);
        //stuck here
    }
    }

Solution

  • You seem to need to inspect Dictionary to see if it contains each word you read, then choose which of KnownWords and UnknownWords to modify.

    void WordStats::ReadTxtFile(){
        std::ifstream ifile(Filename);
        if(!ifile)
        {
            std::cerr << "Error Opening file " << Filename << std::endl;
            exit(1);
        }
    

    I have cleaned up your local declarations, so variables are alive for as little time as necessary.

    Assuming that the file contains words separated by spaces and newlines, read each word

        for (std::string word; ifile >> word; )
        {
    

    Make it lowercase

            transform (word.begin(), word.end(), word.begin(), ::tolower);
    

    Then look to see if it is in Dictionary

            if (Dictionary.count(word))
            {
    

    Record the position in KnownWords[word].

                KnownWords[word].push_back(ifile.tellg());
            }
            else
            {
    

    Or in UnknownWords[word].

                UnknownWords[word].push_back(ifile.tellg()); 
            }
        }
    

    Then display the sizes from those to get the desired output.

        std::cout << KnownWords.size() << " known words read." << std::endl;
        std::cout << UnknownWords.size() << " unknown words read." << std::endl;
    }
    

    You could replace the conditional statement that duplicates the action, with a conditional expression. Note the reference type in the declaration of Words

    WordMap & Words = (Dictionary.count(word) ? KnownWords : UnknownWords);
    Words[word].push_back(ifile.tellg()); 
    

    As a complete function:

    void WordStats::ReadTxtFile(){
        std::ifstream ifile(Filename);
        if(!ifile)
        {
            std::cerr << "Error Opening file " << Filename << std::endl;
            exit(1);
        }
    
        for (std::string word; ifile >> word; )
        {
            transform (word.begin(), word.end(), word.begin(), ::tolower);
            WordMap & Words = (Dictionary.count(word) ? KnownWords : UnknownWords);
            Words[word].push_back(ifile.tellg()); 
        }
    
        std::cout << KnownWords.size() << " known words read." << std::endl;
        std::cout << UnknownWords.size() << " unknown words read." << std::endl;
    }