c++_primer_exercise_1227...

A simple text-query program. Our program will let a user search a given file for words that might occur in it. The result of a query will be the number of times the word occurs and a list of lines on which that word appears. If a word occur more than once on the same line, we'll display that line only once. Lines will be display in ascending order--that is, line 7 should be displayed before line 9, and so on.

/****************************************************
* IDE: VS2013(Text_query.h)
****************************************************/
#ifndef TEXT_QUERY_H_
#define TEXT_QUERY_H_

#include 
   
   
    
    	// for shared_ptr
#include 
    
    
     
     
#include 
     
     
      
      
#include 
      
      
#include 
       
       
         #include 
        
          #include "Query_result.h" // declaration needed for return type in the query function class Query_result; class Text_query { public: typedef std::vector 
         
           ::size_type line_no; Text_query(std::ifstream &); Query_result query(const std::string &sought) const; // void display_map(); // debugging aid: print the map private: std::shared_ptr 
           
           
             > file; // input file // map of each word to the set of the lines in which that word appears std::map 
            
              >> wm; // canonicalizes text: removes punctuation and makes everything lower case static std::string cleanup_str(std::string &); }; #endif /**************************************************** * IDE: VS2013(Text_result.h) ****************************************************/ #ifndef QUERY_RESULT_H_ #define QUERY_RESULT_H_ #include 
             
               #include 
              
                #include 
               
                 #include 
                
                  #include 
                 
                   class Query_result { friend std::ostream &print(std::ostream &, const Query_result &); public: typedef std::vector 
                  
                    ::size_type line_no; typedef std::set 
                   
                     ::const_iterator line_it; Query_result(std::string s, std::shared_ptr 
                     
                     
                       > p, std::shared_ptr 
                       
                       
                         > f) : sought(s), lines(p), file(f) {} private: std::string sought; // word this query represents std::shared_ptr 
                         
                         
                           > lines; // lines it's on std::shared_ptr 
                           
                           
                             > file; // input file }; std::ostream &print(std::ostream &, const Query_result &); #endif /**************************************************** * IDE: VS2013(Text_query.cpp) ****************************************************/ #include "Text_query.h" #include 
                            
                              using std::shared_ptr; #include 
                             
                               using std::istringstream; #include 
                              
                                using std::string; #include 
                               
                                 using std::vector; #include 
                                 using std::map; #include 
                                 
                                   using std::set; #include 
                                  
                                    using std::ifstream; #include 
                                   
                                     using std::ostream; using std::endl; #include 
                                    
                                      // read the input file and build the map of lines to line numbers Text_query::Text_query(ifstream &is) : file(new vector 
                                     
                                       ) { string text; while (getline(is, text)) // for each line in the file { file->push_back(text); // remember this line of text int n = file->size() - 1; // the current line number istringstream line(text); // separate the line into words string word; while (line >> word) // for each word in the line { word = cleanup_str(word); // if word isn't already in wm, subscriptint adds a new entry shared_ptr 
                                       
                                       
                                         > &lines = wm[word]; if (!lines) // that pointer is null the first time we see word { lines.reset(new set 
                                        
                                          ); // allocate a new set } // if a given word occurs more than once in the same line, // the call to insert does nothing. lines->insert(n); } } } // removes punctuations and converts all text to lowercase so that // the quries operate in a case insensitive manner string Text_query::cleanup_str(string &word) { string ret; for (string::iterator it = word.begin(); it != word.end(); ++it) { if (!ispunct(*it)) { ret += tolower(*it); } } return ret; } Query_result Text_query::query(const string &sought) const { // we'll return a pointer to this set if we don't find sought static shared_ptr 
                                          
                                          
                                            > nodata(new set 
                                           
                                             ); // use find and not a subscript to avoid addint words to wm! map 
                                            
                                              >>::const_iterator loc = wm.find(sought); // auto loc = wm.find(sought); // sought const string & if (loc == wm.end()) { return Query_result(sought, nodata, file); } else { return Query_result(sought, loc->second, file); } } ostream &print(ostream &os, const Query_result &qr) { // if the word was found, print the count and all occurrences os << qr.sought << " occurs " << qr.lines->size() << " " \ << (qr.lines->size() > 1 ? "times" : "time") << endl; // print each line in which the word appeared for (auto num : *qr.lines) // for every element in the set { // don't confound the user with text lines starting at 0 os << "\t(line " << num + 1 << ") " \ << *(qr.file->begin() + num) << endl; } return os; } /**************************************************** * IDE: VS2013(query_main.cpp) ****************************************************/ #include 
                                             
                                               using std::string; #include 
                                              
                                                using std::ifstream; #include 
                                               
                                                 using std::cin; using std::cout; using std::cerr; using std::endl; #include "Text_query.h" void run_queries(ifstream &infile) { // infile is an ifstream that is the file we want to query Text_query tq(infile); // store the file and build the query map // iterator with the user: prompt for a word to find and print results while (true) { cout << "enter word to look for, or q to quit: "; string s; if (!(cin >> s) || s == "q") { break; } print(cout, tq.query(s)) << endl; } } int main(void) { // open the file from which user mwill query words string file = "query_main.cpp"; ifstream infile; // open returns void ,so we use the comma operator // to check the state of infile after the open if (!(infile.open(file), infile)) { cerr << "No input file!" << endl; return -1; } run_queries(infile); return 0; } 
                                                
                                               
                                              
                                             
                                            
                                           
                                          
                                         
                                        
                                       
                                      
                                     
                                    
                                   
                                  
                                
                               
                              
                             
                            
                           
                          
                         
                        
                       
                      
                     
                    
                   
                  
                 
                
               
              
             
            
           
          
         
       
     
     
    
    
   
   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值