我正在用 C++ 创建索引器应用程序。 目录的文本文件中的每个唯一单词,我想像这样存储- first_map<"word", second_map<"File Object reference", List{line numbers}>
为了第一次填充这张 map ,我逐字解析目录中的每个文件。为了将数据推送到 map 中,我在使用 like- 时遇到编译错误-
pool[token][it].push_back(count);
如果内部映射值是 int 类型,我认为这不会引发错误。 我也尝试使用 like-
pool[token].insert(std::make_pair(it, count);
这也因错误而失败。 将数据插入此容器的正确方法是什么?
完整的源代码如下-
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <dirent.h>
#include <errno.h>
#include <string.h>
#include<iostream>
#include<iterator>
#include<algorithm>
#include<string>
#include<sstream>
#include<list>
#include<vector>
#include<fstream>
#include<map>
#include<ctime>
class File {
public:
std::string file_name;
int timestamp;
File(std::string name) : file_name(name) {
struct stat st;
int ierr = stat (file_name.c_str(), &st);
if (ierr != 0) {
std::cout << "error in getting timestamp";
}
timestamp = st.st_mtime;
}
};
class Location {
public:
std::vector<File> indexer;
virtual std::map<File*, std::list<int> > find_pattern(std::string& word);
Location(const char* in_dir){
DIR* FD;
struct dirent* in_file;
/* Scanning the in directory */
if (NULL == (FD = opendir (in_dir)))
{
fprintf(stderr, "Error : Failed to open input directory - %s\n", strerror(errno));
throw -1;
}
while ((in_file = readdir(FD)))
{
if (!strcmp (in_file->d_name, "."))
continue;
if (!strcmp (in_file->d_name, ".."))
continue;
indexer.push_back(File(in_file->d_name));
}
}
};
class TextFileLocation : public Location {
public:
std::map<std::string, std::map<File*, std::list<int> > > pool;
TextFileLocation(const char* in_dir) : Location(in_dir){
for(auto it = indexer.begin(); it != indexer.end(); it++){
std::ifstream file1(it->file_name);
if(!file1)
{
std::cout<<"Error opening output file"<<std::endl;
continue;
}
std::string line;
std::string token;
int count = 0;
while (std::getline(file1, line))
{
count++;
std::map<File*, std::list<int> > *file_line =
std::istringstream ss(line);
while(std::getline(ss, token, ' ')) {
if(token.empty())
continue;
pool[token][it].push_back(count);
}
}
}
}
std::map<File*, std::list<int> > find_pattern(std::string& word){
return pool[word];
}
};
最佳答案
好消息:
为了让编译器在有问题的行上消失:
pool[token][&*it].push_back(count);
it
是 std::vector<File>::iterator
, 和 pool
是一个
std::map<std::string, std::map<File*, std::list<int> > >
所以,要得到一个普通的 File *
对于迭代器,“&*”是典型的方法。
坏消息:
这是行不通的。一旦std::vector<File>
重新分配后,指向其内容的所有 native 指针和迭代器都会失效。你的std::map
将留下指向永不落地的指针。
如果这个结构所属的物体被复制或移动,所有东西也会从高轨道上被摧毁。
您需要彻底重新考虑数据和容器的整体设计。
关于c++ - 什么是插入列表 map 的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41008946/