代码之家  ›  专栏  ›  技术社区  ›  Björn Pollex

如何以stl方式将一定数量的字符从文件复制到向量?

  •  6
  • Björn Pollex  · 技术社区  · 14 年前

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

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

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

    编辑 我可以写自己的版本 copy ,但是否有一种方法可以只使用现有组件来实现这一点?

    5 回复  |  直到 13 年前
        1
  •  6
  •   Community CDub    7 年前

    正如人们所注意到的 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::CopySnO() 你可以使用 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
  •  8
  •   avakar    14 年前

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

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

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

        3
  •  1
  •   Steve Jessop    14 年前

    “stl方式”是使用 copy_n ,这是在STL,但不是C++标准。

        4
  •  0
  •   Alexander Rafferty    14 年前
    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.
    

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

        5
  •  0
  •   Potatoswatter    14 年前

    由于@sbi的信用,我忘记了 generate_n .

    这个 streambuf 里面 file 有一个函数 snextc 它返回下一个字符,将其限定为生成器函数,一旦其隐式 this 参数已绑定。

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

    为了 vector ,直接阅读。这对 deque 或者什么。