c++ primer( 文本查询程序)

读取用户指定的任意文本文件,然后允许用户从该文件查找单词,查询的结果是该单词出现的次数,并列出每次出现所在的行,如果某单词在同一行中多次出现,程序将只显示改行的一次。行号按升序显示(int main()&&int main(int argc,charargv)的区别算是了解了,但是跟int mian(int argc,charargv){}中的文件操作还不熟悉,所以文件读取出现异常还不知道从哪里处理)【原来是中文字符不可以】

code:
c++ primer( 文本查询程序)c++ primer( 文本查询程序)

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.cppc++ primer( 文本查询程序)c++ primer( 文本查询程序)

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.cppc++ primer( 文本查询程序)c++ primer( 文本查询程序)

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

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月10日 上午4:14
下一篇 2023年2月10日 上午4:15

相关推荐