Как записать содержимое разных файлов в вектор для дальнейшего использования с getline - PullRequest
0 голосов
/ 08 апреля 2011

Я хочу сохранить содержимое разных файлов в вектор: Вектор (0) = содержимое файла1 Vector (1) = файл содержимого2 ...

Позже мне нужно прочитать строку из каждого индекса этого вектора строка за строкой (getline):

getline(Vector(0), string myString)

Поскольку я читаю на разных сайтах, я не могу использовать vector<istream> myVector.

Так как я могу решить?

Ответы [ 4 ]

3 голосов
/ 08 апреля 2011

Это зависит от размера данных, которыми вы хотите манипулировать.Мои два примера были протестированы.

Вы можете использовать класс, который обрабатывает некоторые необработанные указатели

#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 >,Это базовое решение для небольших файлов, но оно работает.

#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;
}
1 голос
/ 08 апреля 2011

iostream не может быть помещен в любой стандартный контейнер.

Может быть, вы можете сохранить их, используя массив пустых указателей.

0 голосов
/ 08 апреля 2011

Если вы хотите сохранить вектор потоков, рассмотрите возможность использования контейнера указателей или вектора интеллектуальных указателей, что-то вроде этого:

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);

Это просто пример кода - не проверено.

0 голосов
/ 08 апреля 2011

Для ясности, хотите ли вы сохранить дескрипторы файлов, а затем прочитать их позже или прочитать файлы в виде строки типа контейнера и сохранить их в векторе?

Если вы говорите опоследние и файлы представляют собой текстовые файлы, должна быть возможность считывать их в std::string объекты и сохранять их в этой форме.Нет никаких проблем с сохранением возврата каретки и т. Д. В std::string, но имейте в виду, что это решение может не масштабироваться: что произойдет, если вам нужно сохранить файл размером 4 ГБ + или 100 000 файлов в вашем векторе?

...