读取用户指定的任意文本文件,然后允许用户从该文件查找单词,查询的结果是该单词出现的次数,并列出每次出现所在的行,如果某单词在同一行中多次出现,程序将只显示改行的一次。行号按升序显示(int main()&&int main(int argc,charargv)的区别算是了解了,但是跟int mian(int argc,charargv){}中的文件操作还不熟悉,所以文件读取出现异常还不知道从哪里处理)【原来是中文字符不可以】
code:
1 //使用以vector容器存储行号的textQuery类
2 #include "TextQuery.h"
3
4 string make_plural(size_t,const string&,const string&);
5 ifstream &open_file(ifstream&,const string&);
6 void print_results(const vector<TextQuery::line_no>& locs,
7 const string& sought,const TextQuery &file)
8 {
9 //如果找到单词sought,则输出该单词出现的行数
10 typedef vector<TextQuery::line_no >line_nums;
11 line_nums::size_type size=locs.size();
12 cout<<"n"<<sought<<"occurs"<<size<<" "
13 <<make_plural (size,"time","s")<<endl;
14
15 //输出出现该单词的每一行
16 line_nums::const_iterator it=locs.begin();
17 for(;it!=locs.end();++it){
18 cout<<"t(line "<<(*it)+1<<")"<<file.text_line (*it)<<endl;
19 }
20 }
21
22 //main函数接受文件名为参数
23 int main(int argc,char**argv)
24 {
25 //open the file from which user will query words
26 //char fileName[]="h:\test.txt";
27 ifstream infile;
28 if(argc<2||!open_file(infile,argv[1])){
29 cerr<<"No input file"<<endl;
30 cout<<"to here1";
31 system("pause");
32 return EXIT_FAILURE;
33 }
34
35 TextQuery tq;
36 tq.read_file(infile); //建立容器map
37
38 //循环接受用户的查询要求并输出结果
39 while(true){
40 cout<<"enter word to look for,or q to quit:";
41 string s;
42 cin>>s;
43
44 //将s变为小写
45 string ret;
46 for(string::const_iterator it=s.begin();it!=s.end();++it){
47 ret+=tolower(*it);
48 }
49 s=ret;
50
51 //如果用户输入文件结束符或字符‘q’及‘Q’,则结束循环
52 if(!cin||s=="q"||s=="Q") break;
53
54 //获取出现所查询单词所有行的行号
55 vector<TextQuery::line_no>locs=tq.run_query (s);
56
57 //输出出现次数及所有相关文本行
58 print_results(locs,s,tq);
59
60 }
61 system("pause");
62 }
Main.cpp
1 #include "TextQuery.h"
2 #include<sstream>
3
4 string TextQuery::text_line(line_no line)const
5 {
6 if(line<lines_of_text.size())
7 return lines_of_text[line];
8 throw out_of_range("line number out of range");
9 }
10
11 //读输入文件,将每行存储为lines_of_text的一个元素
12 void TextQuery::store_file (ifstream &is)
13 {
14 string textline;
15 while(getline(is,textline))
16 lines_of_text.push_back (textline);
17 }
18
19 //在输入vector中找以空白为间隔的单词
20 //将单词以及出现该单词的行的行号一起放入word_map
21 void TextQuery ::build_map ()
22 {
23 //处理输入vector中的每一行
24 for(line_no line_num=0;line_num!=lines_of_text.size();++line_num)
25 {
26 //一次读一个单词
27 istringstream line(lines_of_text[line_num]);
28 string word;
29 while(line>>word){
30 //去掉标点
31 word=cleanup_str(word);
32 //将行号加入到vector容器中
33 if(word_map.count(word)==0)//该单词不在map容器中
34 //下标操作将加入该单词
35 word_map[word].push_back (line_num);
36 else{
37 if(line_num!=word_map[word].back())
38 //行号与vector容器中最后一个元素不相等
39 word_map[word].push_back (line_num);
40 }
41 }
42 }
43 }
44
45 vector<TextQuery::line_no>
46 TextQuery::run_query(const string &query_word)const
47 {
48 //注意,为了避免在word_map中加入单词,使用find函数而不用下标操作
49 map<string,vector<line_no> >::const_iterator
50 loc=word_map.find(query_word);
51 if(loc==word_map.end())
52 return vector<line_no>(); //找不到,返回空的vector对象
53 else
54 //获取并返回与该单词关联的行号vector对象
55 return loc->second ;
56 }
57
58 //去掉标点并将字母变成小写
59 string TextQuery::cleanup_str (const string &word)
60 {
61 string ret;
62 for(string::const_iterator it=word.begin();it!=word.end();++it){
63 if(!ispunct(*it))
64 ret+=tolower(*it);
65 }
66 return ret;
67 }
68
69 //定义函数make_plural 和open_file的源文件如下:
70 //function.cpp
71 //定义函数make_plural和open_file
72
73 #include<fstream>
74 #include<string>
75
76 using namespace std;
77 //如果ctr不为1,返回word的复数版本
78 string make_plural(size_t ctr,const string &word,const string &ending)
79 {
80 return (ctr==1)?word:word+ending;
81 }
82
83 //打开输入文件流in并绑定到给定的文件
84 ifstream &open_file(ifstream &in,const string&file)
85 {
86 in.close(); //close in case it was already open
87 in.clear(); //clear any existing errors
88 //if the open fails,the stream will be in an invalid state
89 in.open(file.c_str ());
90 return in ; //condition state is good if open succeeded
91 }
TextQuery.cpp
1 #ifndef TEXTQUERY_H
2 #define TEXTQUERY_H
3 #include<string>
4 #include<vector>
5 #include<map>
6 #include<iostream>
7 #include<fstream>
8 #include<cstring>
9 #include<cctype>
10
11 using namespace std;
12
13 class TextQuery{
14 public:
15 typedef string::size_type str_size;
16 typedef vector<string>::size_type line_no;
17
18 //接口:
19 //read_file建立给定文件的内部数据结构
20 void read_file(ifstream &is)
21 {store_file(is);build_map();}
22
23 //run_query查询给定单词并返回该单词所在行的行号集合
24 vector<line_no> run_query(const string&)const;
25
26 //text_line返回输入文件中指定行号对应的行
27 string text_line(line_no) const;
28 private:
29 //read_file所用到辅助函数
30 void store_file(ifstream&); //存储输入文件
31 void build_map(); //将每个单词与一个行号集合相关联
32
33 //保存输入文件
34 vector<string> lines_of_text;
35
36 //将单词与出现该单词的行的行号集合相关联
37 map<string,vector<line_no> >word_map;
38
39 //去掉标点并将字母变成小写
40 static std::string cleanup_str(const std::string&);
41 };
42 #endif
TextQuery.h
原文链接: https://www.cnblogs.com/lyunyu/p/3219569.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/97422
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!