程序的目的是统计单个单词在文本中出现在哪些行
程序由5个小文件构成
问个问题,为什么main.cpp中第18行 qr->c 能正常访问(调试中观察到),但是到了print函数后就不正确了?
main.cpp
// main.cpp
#include "TextQuery.h"
#include "QueryResult.h"
#include <fstream>
#include <memory>
#include <stdexcept>
using namespace std;
void runQueries(ifstream &in)
{
TextQuery tq(in);
while(true){
cout << "输入要查寻的字符串,输入q结束:";
string s;
if(!(cin >> s) || s == "q")
break;
shared_ptr<QueryResult> qr = tq.query(s);
print(cout, qr);
}
}
int main()
{
ifstream in("data/txt.txt");
if(!in)
throw runtime_error("打开文件失败");
runQueries(in);
return 0;
}
TextQuery.h
// TextQuery.h
#ifndef TEXTQUERY_H
#define TEXTQUERY_H
#include <vector>
#include <string>
#include <map>
#include <set>
#include <fstream>
#include <memory>
class QueryResult;
class TextQuery {
public:
TextQuery(std::ifstream &in);
std::shared_ptr<QueryResult> query(const std::string &s);
private:
std::vector<std::string> v;
std::map<std::string, std::set<int>> m;
};
#include "QueryResult.h"
#endif
TextQuery.cpp
// TextQuery.cpp
#include "TextQuery.h"
#include "QueryResult.h"
#include <fstream>
#include <string>
#include <sstream>
#include <set>
#include <memory>
using namespace std;
TextQuery::TextQuery(ifstream &in) {
v.push_back("");
int l = 1;
string line;
while(getline(in, line)) {
v.push_back(line);
istringstream iss(line);
string s;
while(iss >> s)
m[s].insert(l);
++l;
}
}
shared_ptr<QueryResult> TextQuery::query(const string &s) {
shared_ptr<QueryResult> qr = make_shared<QueryResult>(v,s,(m.find(s)==m.end()?set<int>():m[s]));
return qr;
}
QureyResult.h
// QureyResult.h
#ifndef QUERYRESULT_H
#define QUERYRESULT_H
#include "TextQuery.h"
#include <memory>
#include <string>
#include <set>
#include <vector>
#include <iostream>
class QueryResult {
friend void print(std::ostream&, std::shared_ptr<QueryResult>);
public:
QueryResult(std::vector<std::string>& vv, const std::string &strstr, const std::set<int> &s):
v(vv), str(strstr), c(s) {}
private:
std::vector<std::string> &v;
std::string str;
const std::set<int> &c;
};
#endif
QueryResult.cpp
// QueryResult.cpp
#include "QueryResult.h"
#include <iostream>
#include <memory>
using namespace std;
void print(ostream &os, shared_ptr<QueryResult> qr) {
os << qr->str << " 出现了 " << qr->c.size() << " 次" <<endl;
for(const auto &val:qr->c) {
os << "\t(line " << val << ") " << qr->v[val] << endl;
}
}
data/txt.txt
Hello a b c
a m d
no Hello
QueryResult
常量引用一个脱离了上下文的临时变量,导致print错误这里的
set<int>
是临时变量,脱离了作用域后会释放.即在
TextQuery::query
返回后会析构掉,这时的QueryResult.c
指向的是一个无效对象,发生什么事情都是可能的.改成