c++ primer( 文本查询程序)
读取用户指定的任意文本文件,然后允许用户从该文件查找单词,查询的结果是该单词出现的次数,并列出每次出现所在的行,如果某单词在同一行中多次出现,程序将只显示改行的一次。行号按升序显示(int main()&&int main(int argc,char**argv)的区别算是了解了,但是跟int mian(int argc,char**argv){}中的文件操作还不熟悉,所以文件读取出现异常还不知道从哪里处理)【原来是中文字符不可以】
code:
//使用以vector容器存储行号的textQuery类
#include "TextQuery.h" string make_plural(size_t,const string&,const string&);
ifstream &open_file(ifstream&,const string&);
void print_results(const vector<TextQuery::line_no>& locs,
const string& sought,const TextQuery &file)
{
//如果找到单词sought,则输出该单词出现的行数
typedef vector<TextQuery::line_no >line_nums;
line_nums::size_type size=locs.size();
cout<<"\n"<<sought<<"occurs"<<size<<" "
<<make_plural (size,"time","s")<<endl; //输出出现该单词的每一行
line_nums::const_iterator it=locs.begin();
for(;it!=locs.end();++it){
cout<<"\t(line "<<(*it)+<<")"<<file.text_line (*it)<<endl;
}
} //main函数接受文件名为参数
int main(int argc,char**argv)
{
//open the file from which user will query words
//char fileName[]="h:\\test.txt";
ifstream infile;
if(argc<||!open_file(infile,argv[])){
cerr<<"No input file"<<endl;
cout<<"to here1";
system("pause");
return EXIT_FAILURE;
} TextQuery tq;
tq.read_file(infile); //建立容器map //循环接受用户的查询要求并输出结果
while(true){
cout<<"enter word to look for,or q to quit:";
string s;
cin>>s; //将s变为小写
string ret;
for(string::const_iterator it=s.begin();it!=s.end();++it){
ret+=tolower(*it);
}
s=ret; //如果用户输入文件结束符或字符‘q’及‘Q’,则结束循环
if(!cin||s=="q"||s=="Q") break; //获取出现所查询单词所有行的行号
vector<TextQuery::line_no>locs=tq.run_query (s); //输出出现次数及所有相关文本行
print_results(locs,s,tq); }
system("pause");
}
Main.cpp
#include "TextQuery.h"
#include<sstream> string TextQuery::text_line(line_no line)const
{
if(line<lines_of_text.size())
return lines_of_text[line];
throw out_of_range("line number out of range");
} //读输入文件,将每行存储为lines_of_text的一个元素
void TextQuery::store_file (ifstream &is)
{
string textline;
while(getline(is,textline))
lines_of_text.push_back (textline);
} //在输入vector中找以空白为间隔的单词
//将单词以及出现该单词的行的行号一起放入word_map
void TextQuery ::build_map ()
{
//处理输入vector中的每一行
for(line_no line_num=;line_num!=lines_of_text.size();++line_num)
{
//一次读一个单词
istringstream line(lines_of_text[line_num]);
string word;
while(line>>word){
//去掉标点
word=cleanup_str(word);
//将行号加入到vector容器中
if(word_map.count(word)==)//该单词不在map容器中
//下标操作将加入该单词
word_map[word].push_back (line_num);
else{
if(line_num!=word_map[word].back())
//行号与vector容器中最后一个元素不相等
word_map[word].push_back (line_num);
}
}
}
} vector<TextQuery::line_no>
TextQuery::run_query(const string &query_word)const
{
//注意,为了避免在word_map中加入单词,使用find函数而不用下标操作
map<string,vector<line_no> >::const_iterator
loc=word_map.find(query_word);
if(loc==word_map.end())
return vector<line_no>(); //找不到,返回空的vector对象
else
//获取并返回与该单词关联的行号vector对象
return loc->second ;
} //去掉标点并将字母变成小写
string TextQuery::cleanup_str (const string &word)
{
string ret;
for(string::const_iterator it=word.begin();it!=word.end();++it){
if(!ispunct(*it))
ret+=tolower(*it);
}
return ret;
} //定义函数make_plural 和open_file的源文件如下:
//function.cpp
//定义函数make_plural和open_file #include<fstream>
#include<string> using namespace std;
//如果ctr不为1,返回word的复数版本
string make_plural(size_t ctr,const string &word,const string &ending)
{
return (ctr==)?word:word+ending;
} //打开输入文件流in并绑定到给定的文件
ifstream &open_file(ifstream &in,const string&file)
{
in.close(); //close in case it was already open
in.clear(); //clear any existing errors
//if the open fails,the stream will be in an invalid state
in.open(file.c_str ());
return in ; //condition state is good if open succeeded
}
TextQuery.cpp
#ifndef TEXTQUERY_H
#define TEXTQUERY_H
#include<string>
#include<vector>
#include<map>
#include<iostream>
#include<fstream>
#include<cstring>
#include<cctype> using namespace std; class TextQuery{
public:
typedef string::size_type str_size;
typedef vector<string>::size_type line_no; //接口:
//read_file建立给定文件的内部数据结构
void read_file(ifstream &is)
{store_file(is);build_map();} //run_query查询给定单词并返回该单词所在行的行号集合
vector<line_no> run_query(const string&)const; //text_line返回输入文件中指定行号对应的行
string text_line(line_no) const;
private:
//read_file所用到辅助函数
void store_file(ifstream&); //存储输入文件
void build_map(); //将每个单词与一个行号集合相关联 //保存输入文件
vector<string> lines_of_text; //将单词与出现该单词的行的行号集合相关联
map<string,vector<line_no> >word_map; //去掉标点并将字母变成小写
static std::string cleanup_str(const std::string&);
};
#endif
TextQuery.h
c++ primer( 文本查询程序)的更多相关文章
- C++ Primer 学习笔记_38_STL实践与分析(12)--集成的应用程序容器:文本查询程序
STL实践与分析 --容器的综合应用:文本查询程序 引言: 本章中最重点的实例.由于不须要用到multiset与multimap的内容.于是将这一小节提到了前面.通过这个实例程序,大师分析问题的智慧, ...
- C++ 容器的综合应用的一个简单实例——文本查询程序
C++ 容器的综合应用的一个简单实例——文本查询程序 [0. 需求] 最近在粗略学习<C++ Primer 4th>的容器内容,关联容器的章节末尾有个很不错的实例.通过实现一个简单的文本查 ...
- C++ Primer第四版 15.9 再谈文本查询 程序实现
编程过程中发现书本中的示例程序并不完全,某些地方存在错误,现已改正并添加少许注释.. 1 #include<iostream> 2 #include<fstream> #inc ...
- C++ Primer : 第十二章 : 文本查询程序
C++ Primer书上这个例子讲的很不错,写写帮助自己理解标准库和智能指针. .h 文件内容 #include <fstream> #include <iostream> # ...
- C++Primer笔记——文本查询程序(原创,未使用类)
#include <iostream> #include <vector> #include <set> #include <map> #include ...
- C++ Primer中文本查询演示样例Query的实现
近期在看C++ Primer复习C++的语法,看到书中15.9章中的文本查询演示样例时,认为设计得非常不错,于是便动手照着实现了一个,改动了非常久最终执行成功了,从中也学习到了非常多的语法.以下把实现 ...
- c/c++ 继承与多态 文本查询的小例子(非智能指针版本)
问题:在上一篇继承与多态 文本查询的小例子(智能指针版本)在Query类里使用的是智能指针,只把智能指针换成普通的指针,并不添加拷贝构造方法,会发生什么呢? 执行时,代码崩掉. 分析下面一行代码: Q ...
- c/c++ 继承与多态 文本查询的小例子(智能指针版本)
为了更好的理解继承和多态,做一个文本查询的小例子. 接口类:Query有2个方法. eval:查询,返回查询结果类QueryResult rep:得到要查询的文本 客户端程序的使用方法: //查询包含 ...
- 第七篇T语言实例开发,文本与程序的几种打开方法(版5.3)
文本与程序的几种打开方法 文本文件的打开方法 函数名: cmd 命令 函数描述: 执行CMD命令 函数原型: cmd(cmdstr) 命令(cmd命令) 函数参数: cmdstr:cmd命令,此处执行 ...
随机推荐
- WEB组件之间的关系
WEB组件之间的关系: A:重定向的特点: 1:发生客户端 2:地址栏发生变化 3:两个WEB组件不共享request的数据. 4 重定向只能传递文本类型数据 服务端的方法:response.send ...
- 自定义H5页面规范
查看详情页也可支持自定义H5页面,用来展示更多内容. 交互规范 分屏切换,支持横向和竖向,滑动指引需清晰 若详情页加载较慢,需设计loading页,给予用户友好的提示 如有视频,需在底部加上“建议在W ...
- java—— 笔记链接
深入Java关键字null 链接: http://tieba.baidu.com/f?kz=510289524 颜色代码 链接: http://wenku.baidu.com/link?url= ...
- hdu 3631 Shortest Path(Floyd)
题目链接:pid=3631" style="font-size:18px">http://acm.hdu.edu.cn/showproblem.php?pid=36 ...
- C++ inline 函数
(一)inline函数(摘自C++ Primer的第三版) 在函数声明或定义中函数返回类型前加上关键字inline即把min()指定为内联. inline int min(int first, int ...
- CCDictionary&CCArray执行retain()重要点
CCDictionary也需要执行retain(),否则则跟CCArray,返回则释放对象. 在Lua中,忘记了retain(),导致一些出现gCCDictionary:objectForKey(ke ...
- 导出可执行的jar
1.在你要导出的项目上单击右键,在弹出的右键菜单里选择:Export…选项. 2.在弹出的对话框里选择:,然后点击下边的Next; 3.在弹出的对话框里,点击选择导出后的jar存储路径以及文件名.(其 ...
- ERROR<53761> - Plugins - conn=-1 op=-1 msgId=-1 - Connection Bind through PTA failed (91). Retrying...
LDAP6.3在DSCC控制台启动实例完成,但是操作状态显示“意外错误”,查看日志如下: 04/May/2016:21:10:39 +0800] - Sun-Java(tm)-System-Direc ...
- phpmyadmin设置id自增(AUTO_INCREMENT)(转)
phpmyadmin设置id自增(AUTO_INCREMENT) 在A_I 前面打勾:如图 AUTO_INCREMENT =A_I 查看效果
- Android学习手记(2) Activity生命周期
1. 单个Activity的生命周期 当只有一个Activity的时候, 首先执行onCreate->onStart->onResume. 这时, 窗口便显示在屏幕上了. 然后我们按返回键 ...