zoukankan      html  css  js  c++  java
  • c++ primer( 文本查询程序)

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

    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<<"
    "<<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<<"	(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
  • 相关阅读:
    datagridview 保存为excel输出
    将excel导入到datatable
    Json 转换为c#数组
    css 没有图片则隐藏或者显示默认图片
    模拟Get请求
    根据多个字符分隔字符串
    DbHelperSQL
    数据库相关
    json对象
    ajax滚动条懒加载
  • 原文地址:https://www.cnblogs.com/lyunyu/p/3219569.html
Copyright © 2011-2022 走看看