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命令,此处执行 ...
随机推荐
- ubuntu环境配置
网络配置 主要文件:/etc/network/interfaces,这里是IP.网关.掩码等的一些配置: # This file describes the network interfaces av ...
- 搭建完整邮件系统(postfix+dovecot+clamAV+Spamassassin+amavisd-new)
============================ 相关软件: 1. 发送邮件 --- postfix 2. 身份认证 --- sasl2 3. 接收邮件 --- dovecot 4. 防病毒邮 ...
- Bloom Filter概念和原理
Bloom Filter是一种空间效率很高的随机数据结构,它利用位数组很简洁地表示一个集合,并能判断一个元素是否属于这个集合.Bloom Filter的这种高效是有一定代价的:在判断一个元素是否属于某 ...
- ceph主要数据结构解析2-Rados.h文件
(1)文件系统id结构:16个字符组成 struct ceph_fsid { unsigned char fsid[16]; }; 以及对应的比较函数: static inline int ceph_ ...
- 如何让自己的Android程序永不被系统kill
一般来说,在Android系统中,当某进程较长时间不活动,或系统资源比较紧时,该进程可能被系统kill掉,以此来回收一些资源.Android系统会根据进程的优先级来选择性地杀死一些进程,优先级从高到低 ...
- linux下常用基本命令操作
#fdisk -l 查看硬盘信息 cat /proc/cpuinfo 查看CPU信息 free -m 查看内存信息 ethtool eth0 查看网卡信息 df -h 查看硬盘各分区可用空间大小 ca ...
- DiskLruCache 硬盘缓存 使用简介
简介 LruCache只是管理了内存中图片的存储与释放,如果图片从内存中被移除的话,那么又需要从网络上重新加载一次图片,这显然非常耗时.对此,Google又提供了一套硬盘缓存的解决方案:DiskLru ...
- SpringMVC03controller中定义多个方法
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"% ...
- java集合框架01
List 接口存储一组不唯一(可以重复),有序(插入顺序)的对象 01. ArrayList实现了长度可变的数组,在内存中分配连续的空间.遍历元素和随机访问元素的效率比较高 通过看ArrayList的 ...
- 关于IIS部署成功后,局域网其他用户无法访问的问题解决方法
关于win7部署iis后,局域网的其他用户不能访问的问题. 在win7系统中,部署好iis后,自己本地可以发布和预览.但在局域网中的其他用户不可以访问.下面说一下这个原因. 这是因为win7自带的 ...