如何将一定数量的字符从文件复制到STL-way的向量?

时间:2010-09-30 10:55:08

标签: c++ stl

如果我想将文件的内容复制到矢量,我可以这样做:

std::ifstream file("path_to_file");
std::vector<char> buffer(std::istream_iterator<char>(file), 
                         std::istream_iterator<char>());

我的问题是,如果我只想复制第一个n字符,我该怎么做?

编辑我可以编写自己的copy版本,但有没有办法只使用现有组件?

5 个答案:

答案 0 :(得分:8)

亚历山大指出,最快的方法是

std::vector<char> buffer(n);
file.read(&buffer[0], n);

在C ++ 0x中,您可以使用buffer.data()代替&buffer[0];如果n == 0,后者有未定义的行为。

答案 1 :(得分:6)

正如Steve所指出的那样,这需要copy_n(),由于疏忽,它不在当前的标准库中,而是在C ++ 1x中。你可以轻松地自己实现一个,这是我认为正确的一个:

template<class InIt, class OutIt> 
OutIt copy_n(InIt src, OutIt dest, size_t n) 
{
  if (!n) return dest;
  *dest = *src;
  while (--n)
    *++dest = *++src;
  return ++dest; 
} 

请注意std::copy_n()假设输入迭代器能够传递n个对象。从文件中读取时,这可能会有问题。


如果没有std::copy_n(),您可以使用std::generate_n

template< typename InIt >
struct input_generator {
  typedef std::iterator_traits<InIt>::value_type value_type;

  input_generator(InIt begin, InIt end) begin_(begin), end_(end) {}

  value_type operator()()
  {
    assert(it_ != end);
    return *it_++;
  }

  Init begin_;
  Init end_;
};


std::vector<char> buffer;
buffer.reserve(42);

std::generate_n( std::back_inserter(buffer)
               , 42
               , input_generator(std::istream_iterator<char>(file))
               , input_generator(std::istream_iterator<char>()) );

但是,我认为这不比直接从文件中读取avakar showed更有优势。

答案 2 :(得分:1)

“STL方式”是使用copy_n,它是STL而不是C ++标准。

答案 3 :(得分:0)

char *buffer = new char[n];
file.read(buffer,n);
std::vector<char> myVector
for (int i=0;i<n;i++) myVector.push_back(buffer[i]);
delete [] buffer;

// myVector now holds the first n bytes of file.

它可能不是最漂亮或最快捷的方式,但我会这样做。

答案 4 :(得分:0)

归功于@sbi,我忘记了generate_n

streambuffile有一个函数snextc,它返回下一个字符,一旦绑定了隐式this参数,就将其限定为生成函数。

generate_n( back_inserter( buffer ), 42,
            tr1::bind( tr1::mem_fn( &streambuf::snextc ), file.rdbuf() ) );

对于vector,请直接阅读。这对deque或其他任何内容都有好处。