I have a class Word that holds a string and a vector of structs, each struct containing a pointer to a container class, like so:
struct doc { Document* d; int timesMentioned = 0; }; I have an output function that outputs each Word's string and every doc's key in the Word's doc vector. (d1, d2, d3, etc..)
Whenever I output all of them to file, it looks like this:
foo = d3, bar = d3, foobar = d3, etc. With every Word outputting only d3 (The last document that was looped through previous from a given input file. I can post the code for that if needed)
The weird thing is, whenever I output it to console, it works fine. The doc that's associated with each Word is outputted correctly. Any idea why this could happen? I thought it may be a dangling pointer but it outputting to console correctly is curious. I can post the adding docs function or more code if needed.
Here is the code for the Word class:
void Word::createWord(string str) { removePunctuation(str); toLower(str); word = str; } void Word::addDoc(Document& d) { doc newDoc; newDoc.d = &d; newDoc.timesMentioned++; docs.push_back(newDoc); } vector<doc> Word::getDocs() { return docs; } string Word::getWord() { return word; } //Formatting the string, should be irrelevant to this question void Word::removePunctuation(string& str) { string temp = ""; for(int i = 0; i < str.length(); i++) { bool punctual = false; for(int k = 0; k < 42; k++) if(str[i] == punctuals[k]) punctual = true; if(!punctual) temp += str[i]; } str = temp; } void Word::toLower(string& str) { string temp = ""; for(int i = 0; i < str.size(); i++) { char c = str[i]; temp += tolower(c); } str = temp; } Here's where the Words/Documents are instantiated and added to the vector:
void InvertedFileIndex::parseFile(string fileName) { fstream fin, fout; fin.open(fileName.c_str(), fstream::in); if(fin.is_open()) { //Parse input into a single string to the XMLParsing xml_document<> doc; string str, parse = ""; while(fin >> str) parse += str + " "; doc.parse<0>(&parse[0]); xml_node<>* root; root = doc.first_node("mediawiki"); //Iterate through each page int i = 1; for (xml_node<>* page = root->first_node("page"); page; page = page->next_sibling()) { Document d; Word w; string docName = "d" + intToStr(i); xml_node<>* title = page->first_node("title"); d.setTitle(page->first_node("title")->value()); d.setKey(docName); //Find text from document xml_node<>* revision = page->first_node("revision"); xml_node<>* text = revision->first_node("text"); d.setText(text->value()); string docText = text->value(); ////Begin parsing text into words stringstream ss(docText); //create a string stream so we can break it into tokens string item; while (getline(ss, item, ' ')) { Word w; w.createWord(item); w.addDoc(d); toks.push_back(w); } documents.push_back(d); writeToIndex(); i++; } fin.close(); } else cout << "The sample file " << fileName << "could not be opened." << endl; } And here's the output code:
void InvertedFileIndex::writeToIndex() { fstream fout; fout.open("index.txt", fstream::out); if(fout.is_open()) { for(int i = 0; i < toks.size(); i++) { fout << toks[i].getWord() << " = "; cout << toks[i].getWord() << " = "; for(int j = 0; j < toks[i].getDocs().size(); j++) { fout << toks[i].getDocs()[j].d->getKey(); cout << toks[i].getDocs()[j].d->getKey(); fout << ", "; cout << ", "; } fout << endl; cout << endl; } fout.close(); } else cout << "Index file could not be opened." << endl; }