从文件中查找单词

输出所有给定单词所在的行号和该行的内容。

用一个类来完成此功能TextQuery

 
  
#ifndef TEXTQUERY_H
#define TEXTQUERY_H

#include
< iostream >
#include
< fstream >
#include
< sstream >
#include
< string >
#include
< vector >
#include
< map >
#include
< set >

using namespace std;

class TextQuery{
public :
// typedef to make declarations easier
typedef std::vector < std:: string > ::size_type line_no;
/* interface:
*read_file builds internal data structures for the given file
*run_query finds the given word and returns set of ines on which it appears
*test_line returns a requested line from the input file
*/
void read_file(std::ifstream & is )
{
store_file(
is );
build_map();
}
std::
set < line_no > run_query( const std:: string & ) const ;
std::
string text_line(line_no) const ;
private :
// utility functions used by read_file
void store_file(std::ifstream & ); // store input file
void build_map(); // associated each word with a set of line numbers
// remember the whole input file
std::vector < std:: string > lines_of_text;
// map word to set of the lines on which it occurs
std::map < std:: string ,std:: set < line_no > > word_map;
};
// read input file:store each line as element in lines_of_text
void TextQuery::store_file(std::ifstream & is )
{
string textline;
while (getline( is ,textline))
lines_of_text.push_back(textline);
}
// finds whitespace-seperated words in the input vector
// and puts the word in word_map along with the line number
void TextQuery::build_map()
{
// process each line from the input vector
for (line_no line_num = 0 ;line_num != lines_of_text.size(); ++ line_num)
{
// we'll use line to read the text a word at a time
istringstream line(lines_of_text[line_num]);
std::
string word;
while (line >> word)
// add this line number to the set
// subscript will add to to map if it's not already there
word_map[word].insert(line_num);
}
}
set < TextQuery::line_no > TextQuery::run_query( const string & query_word) const
{
// Note:must use find and not subscript the map directly
// to avoid adding words to word_map!
map < string , set < line_no > > ::const_iterator loc = word_map.find(query_word);
if (loc == word_map.end())
return set < line_no > (); // not found,return empty set
else
// fetch and return set of line numbers for this word
return loc -> second;
}
string TextQuery::text_line(line_no line) const
{
if (line < lines_of_text.size())
return lines_of_text[line];
throw ;
}
#endif
主函数

 
  
#include " TextQuery.h "

void print_results( const set < TextQuery::line_no >& , const string & , const TextQuery & );
ifstream
& open_file(ifstream & in , const string & file);
// program takes single argument spesifying the file to query
int main( int argc, char ** argv)
{
// open the file from which user will query words
ifstream infile;
if (argc < 2 ||! open_file(infile,argv[ 1 ]))
{
cerr
<< " No input file! " << endl;
return - 1 ;
}
TextQuery tq;
tq.read_file(infile);
// builds query map;
// iterate with the user:prompt for a word to find and print result
// loop indefinitely;the loop exits is inside the while
while ( true )
{
cout
<< " enter word to look for,or q to quit: " ;
string s;
cin
>> s;
// stop if hit eof on input or a 'q' is enterd
if ( ! cin || s == " q " )
break ;
// get the set of line numbers on which this word appears
set < TextQuery::line_no > loc = tq.run_query(s);
// print count and all occurrences,if any
print_results(loc,s,tq);
}
return 0 ;
}
// return plural version of word if ctr isn't 1
string make_plural(size_t ctr, const string & word, const string & ending)
{
return (ctr == 1 ) ? word:word + ending;
}
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()); // open the file we were given
return in ;
}
void print_results( const set < TextQuery::line_no >& loc, const string & sought, const TextQuery & file)
{
// if the word was found,then print count and all occurrences
typedef set < TextQuery::line_no > line_nums;
line_nums::size_type size
= loc.size();
cout
<< " \n " << sought << " occurs " << size << " " << make_plural(size, " time " , " s " ) << endl; // if size=1 then print "time",or not print "times"
// print each line in which the word appeard
line_nums::const_iterator it = loc.begin();
for (;it != loc.end(); ++ it)
{
cout
<< " \t(line "
// don't confound user with text lines starting at 0
<< ( * it) + 1 << " ) " << file.text_line( * it) << endl;
}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值