C++ 将整个文件读入行向量的最有效方法

C++ 将整个文件读入行向量的最有效方法,c++,vector,fstream,c++14,C++,Vector,Fstream,C++14,我试图找到一种更有效的方法,将整个文件读入一个行向量,定义为std::vector 目前,我写了《天真》一书: std::ifstream file{filepath}; std::vector<std::string> lines; std::string line; while(std::getline(file, line)) lines.push_back(line); 有没有这样的方法可以将文本文件逐行读入向量?有一种非常有趣且相对较新的方法-范围。您可以阅读Eric

我试图找到一种更有效的方法,将整个文件读入一个行向量,定义为
std::vector

目前,我写了《天真》一书:

std::ifstream file{filepath};
std::vector<std::string> lines;

std::string line;
while(std::getline(file, line)) lines.push_back(line);

有没有这样的方法可以将文本文件逐行读入向量?

有一种非常有趣且相对较新的方法-范围。您可以阅读Eric Niebler的非常有趣的文章:

关于fast getlines替代方案


以下代码中的某些内容可能会起作用

struct FileContents
{
   // Contents of the file.
   std::string contents;

   // Each line consists of two indices.
   struct line { std::string::size_type begin; std::string::size_type end;};

   // List of lines.
   std::vector<line> lines;
};

void readFileContents(std::string const& file,
                      FileContents& fileContents)
{
   std::ifstream ifs(file);
   if ( !ifs )
   {
      // Deal with error.
      return;
   }

   // Get the size of the file.
   ifs.seekg(0, std::ios::end);
   std::fstream::pos_type size = ifs.tellg();

   // Reserve space to read the file contents.
   fileContents.contents.assign(static_cast<std::string::size_type>(size), '\0');

   // Read the file contents.
   ifs.seekg(0, std::ios::beg);
   ifs.read(&fileContents.contents[0], size);
   ifs.close();

   // Divide the contents of the file into lines.
   FileContents::line line = {0, 0};
   std::string::size_type pos;
   while ( (pos = fileContents.contents.find('\n', line.begin)) != std::string::npos )
   {
      line.end = pos+1;
      fileContents.lines.push_back(line);
      line.begin = line.end;
   }
   line.end = fileContents.contents.size();
   if ( line.begin < fileContents.contents.size() )
   {
      fileContents.lines.push_back(line);
   }
}
struct FileContents
{
//文件的内容。
std::字符串内容;
//每行由两个索引组成。
结构行{std::string::size_-type-begin;std::string::size_-type-end;};
//行列表。
std::矢量线;
};
void readFileContents(std::string const&file),
文件内容(FileContents&FileContents)
{
std::ifstream ifs(文件);
如果(!ifs)
{
//处理错误。
返回;
}
//获取文件的大小。
ifs.seekg(0,标准::ios::结束);
std::fstream::pos_type size=ifs.tellg();
//保留空间以读取文件内容。
fileContents.contents.assign(静态类型转换(大小),'\0');
//读取文件内容。
如果seekg(0,标准::ios::beg);
ifs.read(&fileContents.contents[0],大小);
ifs.close();
//将文件内容分成几行。
FileContents::line line={0,0};
std::string::size\u type pos;
而((pos=fileContents.contents.find('\n',line.begin))!=std::string::npos)
{
line.end=pos+1;
fileContents.lines.push_back(行);
line.begin=line.end;
}
line.end=fileContents.contents.size();
if(line.begin
如果在
移动后再次使用对象,则
推回
将不会复制
std::move(line)
@JonathanPotter?我不喜欢那样。不过,我会使用
emplace\u back
。流迭代器方法在我的测试中非常慢。为了获得最大的速度,我会尝试将整个文件读取到一个预先分配的向量中,然后将其拆分为单独的字符串。@CoffeeandCode
move
保证使moved from对象保持一致状态,所以我看不出有什么问题。@Galik:要么在向量中分配旧字符串,要么分配新字符串,对此你无能为力。至少你没有复制实际的字符。
struct FileContents
{
   // Contents of the file.
   std::string contents;

   // Each line consists of two indices.
   struct line { std::string::size_type begin; std::string::size_type end;};

   // List of lines.
   std::vector<line> lines;
};

void readFileContents(std::string const& file,
                      FileContents& fileContents)
{
   std::ifstream ifs(file);
   if ( !ifs )
   {
      // Deal with error.
      return;
   }

   // Get the size of the file.
   ifs.seekg(0, std::ios::end);
   std::fstream::pos_type size = ifs.tellg();

   // Reserve space to read the file contents.
   fileContents.contents.assign(static_cast<std::string::size_type>(size), '\0');

   // Read the file contents.
   ifs.seekg(0, std::ios::beg);
   ifs.read(&fileContents.contents[0], size);
   ifs.close();

   // Divide the contents of the file into lines.
   FileContents::line line = {0, 0};
   std::string::size_type pos;
   while ( (pos = fileContents.contents.find('\n', line.begin)) != std::string::npos )
   {
      line.end = pos+1;
      fileContents.lines.push_back(line);
      line.begin = line.end;
   }
   line.end = fileContents.contents.size();
   if ( line.begin < fileContents.contents.size() )
   {
      fileContents.lines.push_back(line);
   }
}