Class segmentation fault
Hello lads, I get a segmentation fault when I put "you" as input. Sorry for the messy code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
#include <iostream>
#include <string>
#include <fstream>
#include "TextQuery.h"
using namespace std;
void runQueries(ifstream &infile)
{
TextQuery tq(infile);
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()
{
ifstream iF("input.txt");
runQueries(iF);
return 0;
}
|
Classes:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
|
#ifndef TEXTQUERY_H
#define TEXTQUERY_H
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <fstream>
#include <map>
#include <set>
class TextQuery;
class QueryResult {
public:
QueryResult() = default;
QueryResult(std::string w) : word(w) {}
std::vector<std::string>& getLines() { return lines; }
std::set<unsigned>& getWL() { return WL; }
std::string& w() { return word; }
unsigned& occ() { return occur; }
bool empty() { return (WL.empty()) ? true : false; }
private:
std::vector<std::string> lines;
std::set<unsigned> WL;
std::string word;
unsigned occur = 0;
};
std::ostream &print(std::ostream &o, QueryResult qt)
{
if (!qt.empty()) {
o << "element occurs " << qt.occ() << " times\n";
for (auto beg = qt.getWL().cbegin(); beg != qt.getWL().cend(); ++beg) {
std::cout << "\t(line " << *beg << ")" << qt.getLines()[*beg-1] << "\n";
}
o << "\b";
return o;
} else {
o << qt.w() << " not in text.";
return o;
}
}
class TextQuery {
public:
TextQuery() = default;
TextQuery(std::ifstream &iF) {
std::string l, w;
if (iF) {
for (unsigned lNum = 1; !iF.eof(); ++lNum) {
getline(iF, l);
lines.push_back(l);
std::istringstream iL(l);
while (iL >> w) {
++(WL[w].first);
WL[w].second.insert(lNum);
}
}
}
}
QueryResult query(const std::string &);
std::vector<std::string>& getLines() { return lines; }
std::map<std::string, std::pair<unsigned, std::set<unsigned>>>& getWL() { return WL; }
private:
std::vector<std::string> lines;
std::map<std::string, std::pair<unsigned, std::set<unsigned>>> WL;
};
QueryResult TextQuery::query(const std::string &w)
{
QueryResult qt(w);
qt.getWL() = (this->WL)[w].second;
qt.occ() = (this->WL)[w].first;
for (auto beg = (this->getWL())[w].second.cbegin(); beg != (this->getWL())[w].second.cend(); ++beg) {
qt.getLines().push_back(lines[*beg-1]);
}
return qt;
}
#endif
|
input.txt
hello hello you there you there
oh hello hello yea i am here
oh how are you
i am fine you
good you want to eat
yea sure we can eat
|
Edit:
Solved
Okay finally got it, my set held the line numbers that had the word on them from the actual text(held by the vector in TextQuery)
I was using the data of that to index the vector that only held the lines that had the word in them.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
|
#ifndef TEXTQUERY_H
#define TEXTQUERY_H
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <fstream>
#include <map>
#include <set>
class TextQuery;
class QueryResult {
public:
QueryResult() = default;
QueryResult(std::string w) : word(w) {}
std::vector<std::string>& getLines() { return lines; }
std::set<unsigned>& getWL() { return WL; }
std::string& w() { return word; }
unsigned& occ() { return occur; }
bool empty() { return (WL.empty()) ? true : false; }
private:
std::vector<std::string> lines;
std::set<unsigned> WL;
std::string word;
unsigned occur = 0;
};
std::ostream &print(std::ostream &o, QueryResult qt)
{
if (!qt.empty()) {
o << "element occurs " << qt.occ() << " times\n";
auto beg = qt.getWL().cbegin();
unsigned i = 0;
while (beg != qt.getWL().cend() && i != qt.getWL().size()) {
std::cout << "\t(line " << *beg << ")" << qt.getLines()[i] << "\n";
// problem here ^
++beg;
++i;
}
o << "\b";
return o;
} else {
o << qt.w() << " not in text.";
return o;
}
}
class TextQuery {
public:
TextQuery() = default;
TextQuery(std::ifstream &iF) {
std::string l, w;
if (iF) {
for (unsigned lNum = 1; !iF.eof(); ++lNum) {
getline(iF, l);
lines.push_back(l);
std::istringstream iL(l);
while (iL >> w) {
++(WL[w].first);
WL[w].second.insert(lNum);
}
}
}
}
QueryResult query(const std::string &);
std::vector<std::string>& getLines() { return lines; }
std::map<std::string, std::pair<unsigned, std::set<unsigned>>>& getWL() { return WL; }
private:
std::vector<std::string> lines;
std::map<std::string, std::pair<unsigned, std::set<unsigned>>> WL;
};
QueryResult TextQuery::query(const std::string &w)
{
QueryResult qt(w);
qt.getWL() = (this->WL)[w].second;
qt.occ() = (this->WL)[w].first;
for (auto beg = (this->getWL())[w].second.cbegin(); beg != (this->getWL())[w].second.cend(); ++beg) {
qt.getLines().push_back(lines[*beg-1]);
}
return qt;
}
#endif
|
Last edited on
Topic archived. No new replies allowed.