Requirement description
Users are allowed to query words in a given file. The query results are a list of the number of times words appear in the file and the rows they are in. If a word appears multiple times in a line, the line is listed only once. The guild outputs in ascending order -- that is, line 7 is displayed before line 9, and so on.
Operation results:
main function:
#include <iostream> #include <fstream> #include <string> #include <sstream> #include "inclass.h" #include "outclass.h" using namespace std; int main(int argc, char** argv) { ifstream infile("text.txt"); TextQuery qu(infile); string str; while(true){ if(!(cin>>str) || str=="q") break; print(cout,qu.query(str))<<endl; } return 0; }
Incass class: (mainly controls reading data from files)
#include<set> #include<map> #include<memory> #include"outclass.h" using namespace std; #pragma once class TextQuery{ public: TextQuery(){} TextQuery(ifstream & infile); TextPrint query(const string& str) const; private: //c++ 11 New Standard Library: Intelligent Pointer shared_ptr<vector<string>> file; map<string,shared_ptr<set<int>>> mp; }; TextQuery::TextQuery(ifstream& infile):file(new vector<string>){ string line = "",word = ""; int i = 1; while(getline(infile,line)){ file->push_back(line); istringstream is(line); while(is>>word){ //Reference to pointers auto &cur = mp[word]; if(!cur) cur.reset(new set<int>); cur->insert(i); } ++i; } } TextPrint TextQuery::query(const string& str)const{ static shared_ptr<set<int>> nodata(new set<int>); auto loc = mp.find(str); if(loc == mp.end()) return TextPrint(str,nodata,file); return TextPrint(str,loc->second,file); }
outclass class class: (print results)
#include<iostream> #include<string> #include<memory> #include<set> using namespace std; #pragma once class TextPrint{ public: TextPrint(){}; TextPrint(string find,shared_ptr<set<int>> l,shared_ptr<vector<string>> f): find(find),line_nums(l),file(f){} friend ostream& print(ostream&, const TextPrint&); private: string find; shared_ptr<set<int>> line_nums; shared_ptr<vector<string>> file; }; ostream& print(ostream& os,const TextPrint& qr){ os<<qr.find<<" occurs "<<qr.line_nums->size()<<" time(s)"<<endl; for(auto num:*qr.line_nums){ os<<"\t(line "<< num <<") "<<*(qr.file->begin()+num-1)<<endl; } return os; }
In fact, in this text query program, there is no need to write text processing and printing in two different classes, mainly for the purpose of practicing the use of smart pointers and sharing data between classes.