Reading "C ++ primer" (4th), page 325th provides a textquery example, which summarizes the usage of STL containers, but the book does not provide continuous and complete code, after the experiment, I recorded the program to facilitate future searching for memories. The function of this program is to find the number of occurrences of a word in the input text file and Its row number.
First, the textquery Class header file textquery. h:
# Ifndef textquery_h _ # define textquery_h _ # include <iostream> # include <fstream> // the header file of ifstream # include <set> # include <string> # include <vector> # include <map> # include <stdlib. h> // exit_falure header file # include <sstream> // istringstream header file # include <utility> // pairs header file using namespace STD; Class textquery {public: typedef STD :: vector <STD: String >:: size_type line_no; void read_file (STD: ifstream & IS) {store_file (is); build_map ();} STD :: set <line_no> run_query (const STD: string &) const; STD: String text_line (line_no) const; private: void store_file (STD: ifstream &); void build_map (); STD: vector <STD: String> lines_of_text; STD: Map <STD: String, STD: Set <line_no> word_map ;}; ifstream & open_file (ifstream & in, const string & file); void print_results (const set <textquery: line_no> & locs, const string & sought, const textquery & file );
Then there is textquery. cpp:
#include "TextQuery.h"#include <stdexcept>void TextQuery::store_file(ifstream &is){string textline;while (getline(is, textline))lines_of_text.push_back(textline);}void TextQuery::build_map(){for (line_no line_num = 0; line_num != lines_of_text.size(); ++line_num) {istringstream line(lines_of_text[line_num]);string word;while (line >> word)word_map[word].insert(line_num);}}set<TextQuery::line_no> TextQuery::run_query(const string &query_word) const{map<string, set<line_no> >::const_iterator loc = word_map.find(query_word);if (loc == word_map.end())return set<line_no>();elsereturn loc->second;}string TextQuery::text_line(line_no line) const{if (line < lines_of_text.size())return lines_of_text[line];throw std::out_of_range("line number out of range");}string make_plural(size_t ctr, const string &word, const string &ending){return (ctr == 1) ? word : word + ending;}ifstream &open_file(ifstream &in, const string &file){in.close(); // close in case it was already openin.clear(); // clear any existing errors // if the open fails, the stream will be in an invalid statein.open(file.c_str()); // open the file we were givenreturn in; // condition state is good if open succeeded}void print_results(const set<TextQuery::line_no>& locs, const string& sought, const TextQuery &file){typedef set<TextQuery::line_no> line_nums;line_nums::size_type size = locs.size();cout << "\n" << sought << " occurs " << size << " "<< make_plural(size, "time", "s") << endl;line_nums::const_iterator it = locs.begin();for (; it != locs.end(); ++it) {cout << "\t(line" << (*it) + 1 << ")" << file.text_line(*it) << endl;}}
Finally, Main. cpp:
#include "TextQuery.h"using namespace std;int main(int argc, char **argv) {ifstream infile;if (argc < 2 || !open_file(infile, argv[1])) {cerr << "No input file!" << endl;return EXIT_FAILURE;}TextQuery tq;tq.read_file(infile);while (true) {cout << "enter word to look for,or q to quit" << endl;string s;cin >> s;if (!cin || s == "q")break;set<TextQuery::line_no> locs = tq.run_query(s);print_results(locs, s, tq);}return 0;}
I tested the compilation on G ++ in Ubuntu 13.04:
Test result: