如何将不同文件的内容写入向量以供 getline 进一步使用

发布于 2024-10-30 20:26:42 字数 253 浏览 1 评论 0原文

我想将不同文件的内容保存到一个向量中: 矢量(0) = 内容文件1 矢量(1) = 内容文件2 ...

稍后,我需要逐行读出该向量的每个索引(getline):

getline(Vector(0), string myString)

当我在不同的站点上阅读时,我不能使用 vector; myVector

那么我该如何解决呢?

I want to save the content of different files to a vector:
Vector(0) = Content File1
Vector(1) = Content File2
...

Later on I need to read out from each index of this vector line by line (getline):

getline(Vector(0), string myString)

As I read on different sites, I can't use vector<istream> myVector.

So how can I solve?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

忘羡 2024-11-06 20:26:42

这取决于您要操作的数据的大小。我的两个样品已经过测试。

您可以使用处理一些原始指针的类

#include <iostream>
#include <fstream>
#include <vector>
#include <string>

class file_vector 
{
public:
  file_vector()
  {}

  virtual ~file_vector()
  {
    for( std::vector< std::ifstream* >::iterator it = m_file_streams.begin(); it != m_file_streams.begin(); it++)
    {
      std::ifstream * p_stream = *it;
      delete p_stream;
    }
  }

  void append_file(const std::string& file_name)
  {
    std::ifstream * p_stream = new std::ifstream( file_name.c_str() );
    if(p_stream->is_open())
      m_file_streams.push_back(p_stream);
    else
      delete p_stream;
  }

  void reset()
  {
    for( std::vector< std::ifstream* >::iterator it = m_file_streams.begin(); it != m_file_streams.end(); it++)
    {
      std::ifstream * p_stream = *it;
      p_stream->seekg(0,p_stream->beg);
    }
  }

  size_t size()
  {
    return m_file_streams.size();
  }

  std::ifstream & get(size_t index)
  {
    return * m_file_streams.at(index); // Using at because of index check
  }

  std::ifstream & operator [] (size_t index)
  {
    return get(index);
  }

private:
  std::vector< std::ifstream* > m_file_streams;
};


int main()
{
  file_vector files_content;
  files_content.append_file("file1.txt");
  files_content.append_file("file2.txt");
  files_content.append_file("file3.txt");

  for(size_t i = 0; i < files_content.size(); i++)
  {
    std::string current_line;
    while(std::getline(files_content[i],current_line))
      std::cout << current_line << std::endl;
  }

  files_content.reset(); // To make getline usable again


  return 0;
}

或 std::vector< std::向量< std::string > >。这是小文件的基本解决方案,但它确实有效。

#include <iostream>
#include <fstream>
#include <vector>
#include <string>

typedef std::vector< std::string > string_vec;
typedef std::vector< std::string >::iterator string_it;

typedef std::vector< string_vec> file_vec;
typedef std::vector< string_vec >::iterator file_it;

int main()
{
  string_vec file_names;
  file_names.push_back("file1.txt");
  file_names.push_back("file2.txt");
  file_names.push_back("file3.txt");

  file_vec files_content;
  string_vec empty_file_content;

  for(string_it file_name = file_names.begin(); file_name != file_names.end(); file_name++)
  {
    std::ifstream input_stream( file_name->c_str() );
    files_content.push_back(empty_file_content);

    if(input_stream.is_open())
    {
      string_vec & current_file_content = files_content[ files_content.size() - 1 ];
      std::string current_line;
      while(std::getline(input_stream, current_line))
        current_file_content.push_back(current_line);
    }
  }

  // Some stuff

    // Reading the content later on
  for(file_it file = files_content.begin(); file != files_content.end(); file++)
  {
    for(string_it line = file->begin(); line != file->end(); line++)
    {
      std::cout << *line << std::endl;
    }
  }

  return 0;
}

It depends on the size of the data you want to manipulate. My two samples has been tested.

You can use a class which handles some raw pointers

#include <iostream>
#include <fstream>
#include <vector>
#include <string>

class file_vector 
{
public:
  file_vector()
  {}

  virtual ~file_vector()
  {
    for( std::vector< std::ifstream* >::iterator it = m_file_streams.begin(); it != m_file_streams.begin(); it++)
    {
      std::ifstream * p_stream = *it;
      delete p_stream;
    }
  }

  void append_file(const std::string& file_name)
  {
    std::ifstream * p_stream = new std::ifstream( file_name.c_str() );
    if(p_stream->is_open())
      m_file_streams.push_back(p_stream);
    else
      delete p_stream;
  }

  void reset()
  {
    for( std::vector< std::ifstream* >::iterator it = m_file_streams.begin(); it != m_file_streams.end(); it++)
    {
      std::ifstream * p_stream = *it;
      p_stream->seekg(0,p_stream->beg);
    }
  }

  size_t size()
  {
    return m_file_streams.size();
  }

  std::ifstream & get(size_t index)
  {
    return * m_file_streams.at(index); // Using at because of index check
  }

  std::ifstream & operator [] (size_t index)
  {
    return get(index);
  }

private:
  std::vector< std::ifstream* > m_file_streams;
};


int main()
{
  file_vector files_content;
  files_content.append_file("file1.txt");
  files_content.append_file("file2.txt");
  files_content.append_file("file3.txt");

  for(size_t i = 0; i < files_content.size(); i++)
  {
    std::string current_line;
    while(std::getline(files_content[i],current_line))
      std::cout << current_line << std::endl;
  }

  files_content.reset(); // To make getline usable again


  return 0;
}

Or a std::vector< std::vector< std::string > >. That's a basic solution for small files but it works.

#include <iostream>
#include <fstream>
#include <vector>
#include <string>

typedef std::vector< std::string > string_vec;
typedef std::vector< std::string >::iterator string_it;

typedef std::vector< string_vec> file_vec;
typedef std::vector< string_vec >::iterator file_it;

int main()
{
  string_vec file_names;
  file_names.push_back("file1.txt");
  file_names.push_back("file2.txt");
  file_names.push_back("file3.txt");

  file_vec files_content;
  string_vec empty_file_content;

  for(string_it file_name = file_names.begin(); file_name != file_names.end(); file_name++)
  {
    std::ifstream input_stream( file_name->c_str() );
    files_content.push_back(empty_file_content);

    if(input_stream.is_open())
    {
      string_vec & current_file_content = files_content[ files_content.size() - 1 ];
      std::string current_line;
      while(std::getline(input_stream, current_line))
        current_file_content.push_back(current_line);
    }
  }

  // Some stuff

    // Reading the content later on
  for(file_it file = files_content.begin(); file != files_content.end(); file++)
  {
    for(string_it line = file->begin(); line != file->end(); line++)
    {
      std::cout << *line << std::endl;
    }
  }

  return 0;
}
执笏见 2024-11-06 20:26:42

iostream 不能放入任何 std 容器中。

也许您可以使用空指针数组来保存它们。

iostream cannot be put into any std container.

Maybe you can save them using a void pointer array.

少女情怀诗 2024-11-06 20:26:42

需要明确的是,您是否想要存储文件句柄,然后稍后从文件中读取,或者将文件读入类似容器的字符串并将其存储在向量中?

如果您谈论的是后者并且文件是文本文件,则应该可以将它们读入 std::string 对象并以该形式存储它们。在 std::string 中存储回车符等没有问题,但请记住,此解决方案可能无法扩展:如果您需要在您的存储中存储 4Gb+ 或 100,000 个文件,会发生什么情况向量?

To be clear, are you wanting to store the file handles and then read from the files later or read the files into a string like container and store these in the vector?

If you're talking about the latter and the files are text files, it should be possible to read them into std::string objects and store them in that form. There's no problem in storing carriage return etc. in a std::string but bear in mind that this solution may not be scaleable: What happens if you need to store a file that's 4Gb+ or 100,000 files in your vector?

孤蝉 2024-11-06 20:26:42

如果您想存储流向量,请考虑使用指针容器或智能指针向量,如下所示:

typedef boost::shared_ptr<std::istream> stream_ptr
std::vector<stream_ptr> stream_container;

// Then add your streams
stream_container.push_back(stream_ptr(new std::ifstream("f1")));
stream_container.push_back(stream_ptr(new std::ifstream("f2")));
stream_container.push_back(stream_ptr(new std::ifstream("f3")));
:

// Then iterate through and call get line..
std::vector<stream_ptr>::iterator it(stream_container.begin()), end(stream_container.end());

std::string sv;
for(; it != end; ++it)
  getline(**it, sv);

这只是示例代码 - 未经测试。

If you want to store a vector of streams, consider using a pointer container or a a vector of smart pointers, something like this:

typedef boost::shared_ptr<std::istream> stream_ptr
std::vector<stream_ptr> stream_container;

// Then add your streams
stream_container.push_back(stream_ptr(new std::ifstream("f1")));
stream_container.push_back(stream_ptr(new std::ifstream("f2")));
stream_container.push_back(stream_ptr(new std::ifstream("f3")));
:

// Then iterate through and call get line..
std::vector<stream_ptr>::iterator it(stream_container.begin()), end(stream_container.end());

std::string sv;
for(; it != end; ++it)
  getline(**it, sv);

This is just example code - untested.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文