昨天学习了容器和文件流操作,写了C++Primer书中的TextQuery类。
textquery.h
#ifndef TEXTQUERY_H
#define TEXTQUERY_H
#include <iostream>
#include <string>
#include <map>
#include <set>
#include <vector>
#include <fstream>
using namespace std;
class TextQuery
{
public:
void read_file(ifstream &is);//从文件中读一行,并保存到VECTOR容器中
set<vector<string>::size_type> run_query(const string &) const;//返回string对象的所有行的行号
string text_line(vector<string>::size_type) const;//返回输入文本中该行号对应的文本行
void print(set<vector<string>::size_type>&,TextQuery &);
private:
void store_file(ifstream &);//函数读入文件,并将文件内容存储在vector容器中
void build_map();//将每一行分解为各个单词,创建map容器对象,同时记录每个单词出现的行号
vector<string> lines_of_text;
map<string,set<vector<string>::size_type> > word_map;
};
#endif
textquery.cpp
#include "textquery.h"
#include <sstream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <iostream>
#include <fstream>
#include <cctype>
#include <cstring>
#include <stdexcept>
using namespace std;
void TextQuery::read_file(ifstream &is)
{
store_file(is);
build_map();
}
set<vector<string>::size_type> TextQuery::run_query(const string &str) const
{
map<string,set<vector<string>::size_type> >::const_iterator it = word_map.find(str);
if(it == word_map.end())
return set<vector<string>::size_type>();
else return it->second;
}
string TextQuery::text_line(vector<string>::size_type line) const
{
if (line < lines_of_text.size())
return lines_of_text[line];
throw out_of_range("line number out of range");
}
void TextQuery::store_file(ifstream &is)
{
string textline;
while (getline(is,textline))
{
lines_of_text.push_back(textline);
}
}
void TextQuery::build_map()
{
vector<string>::iterator st=lines_of_text.begin();
int i=0;
string word;
while (st!=lines_of_text.end())
{
istringstream stream(*st);
while (stream >> word)
{
word_map[word].insert(i);//这种写法的解释,word作为键值在word_map里面时,word_map[word]是一个set容器。insert是对这个set进行插入,当word作为键值不在word_map时,word_map[word]会先创建一个关联,word插入word_map并关联一个空的set,然后对这个空的set执行insert。
}
i++;
st++;
}
}
void TextQuery::print(set<vector<string>::size_type> &locs,TextQuery &tq)
{
vector<string>::size_type size = locs.size();
set<vector<string>::size_type>::const_iterator it=locs.begin();
cout<<"There total "<<size<<" rows:"<<endl;
for (;it != locs.end();++it)
{
cout<<"\t(line "<<(*it)+1<<") "<<tq.text_line(*it) <<endl;
}
}
main.cpp
#include "textquery.h"
ifstream& open_file(ifstream &in,const string &filename)
{
in.close();
in.clear();
in.open(filename.c_str());
return in;
}
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);
cout<<"input the query string or q to exit:";
string str;
cin>>str;
if (str == "q" || str == "Q" ||!cin)
{
exit(1);
}
else{
set<vector<string>::size_type> locs = tq.run_query(str);
tq.print(locs,tq);
}
return 0;
}
argv参数传入的方法:VC6.0编译器打开菜单-->Project-->Settings-->Debug,在第二栏Program arguments中输入文件路径,比如输入D:\\test.txt