I want to output the times that a words occurs in a text and output the lines that contains the word, but when I output vector[*beg]
I found that vector is empty!
I think the problem lie in using ifstream &ifs
twice:
auto wordMap=setMap(ifs);
std::vector<std::string> vvector = read_to_vector(ifs);
If I exchange the two statements, it broke down immediately
I want to know where the problem lies and how to solve.
#include <iostream>
#include<vector>
#include <fstream>
#include <string>
#include <set>
#include <map>
#include <sstream>
#include <memory>
std::vector<std::string> read_to_vector(std::ifstream &ifs)
{
std::string lines;
std::vector<std::string> sentences;
while (std::getline(ifs, lines))
{
sentences.push_back(lines);
}
return sentences;
}
std::map<std::string,std::set<size_t>> setMap(std::ifstream &ifs)
{
std::vector<std::string> word_vector = read_to_vector(ifs);
std::string lines, words;
std::map < std::string, std::set<size_t> > word_map;
for (size_t i = 0; i < word_vector.size(); i++)
{
//i is the current line_num
std::istringstream stream(word_vector[i]);
while (stream >> words)
{
word_map[words].insert(i);
}
}
return word_map;
}
void print(std::ifstream &ifs)
{
auto wordMap=setMap(ifs);
std::vector<std::string> vvector = read_to_vector(ifs);
std::string search;
std::cout << "please input the word that you wanna search" << "\n";
std::cin >> search;
auto findw = wordMap.find(search);
if (findw != wordMap.cend())
std::cout << search << " occurs " << findw->second.size()
<< " times : " << std::endl;
std::set<size_t> lineNum = findw->second;
//it is a set
auto beg = lineNum.begin();
while (beg != lineNum.end())
{
std::cout << *beg;
//std::cout<<vvector[*beg];
beg++;
}
for (auto c : vvector)
std::cout << c << std::endl;
if (vvector.empty())
std::cout << "vector is empty!";
//WTF!!! vector is empty!!!
}
int main()
{
std::ifstream ifs;
ifs.open("text.txt",std::ios::in);
print(ifs);
ifs.close();
}
When you call read_to_vector
for first time (in setMap
) it reaches to the end of file, so when next time you call it(in print
), vector will be empty. reset the cursor before reading the lines in read_to_vector
. Change it to:
std::vector<std::string> read_to_vector(std::ifstream &ifs)
{
ifs.seekg (0, ifs.beg);//add this
std::string lines;
std::vector<std::string> sentences;
while (std::getline(ifs, lines))
{
sentences.push_back(lines);
}
return sentences;
}
Suggestion
I think it's better read the file once and then pass the vector around:
std::map<std::string,std::set<size_t>> setMap(std::vector<std::string> word_vector )
{
//std::vector<std::string> word_vector = read_to_vector(ifs);
std::string lines, words;
std::map < std::string, std::set<size_t> > word_map;
//some code
}
and then
void print(std::ifstream &ifs)
{
std::vector<std::string> vvector = read_to_vector(ifs);
auto wordMap=setMap(vvector);
// some code
}