How to copy a certain number of chars from a file to a vector the STL-way?

前端 未结 5 815
不知归路
不知归路 2020-12-11 05:27

If I want to copy the contents of a file to a vector, I can do it like that:

std::ifstream file(\"path_to_file\");
std::vector buffer(std::istrea         


        
相关标签:
5条回答
  • 2020-12-11 05:49
    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.
    

    It may not be the prettiest or quickest way, but it is how I would do it.

    0 讨论(0)
  • 2020-12-11 05:54

    Credit due to @sbi, I forgot about generate_n.

    The streambuf inside file has a function snextc which returns the next character, qualifying it as a generator function, once its implicit this argument is bound.

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

    For vector, just read directly. This is good for deque or whatever.

    0 讨论(0)
  • 2020-12-11 06:06

    As Alexander points out, the fastest way would be

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

    In C++0x, you can use buffer.data() instead of &buffer[0]; the latter has undefined behavior if n == 0.

    0 讨论(0)
  • 2020-12-11 06:07

    As was noted by Steve, this would need copy_n(), which, due to an oversight, isn't in the current standard library, but will be in C++1x. You can implement one yourself easily, here's one I believe to be correct:

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

    Note that std::copy_n() presumes the input iterator to be able to deliver n objects. When reading from a file, this could be problematic.


    Absent of std::copy_n(), you could use 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>()) );
    

    However, I don't see this as an advantage over reading directly from the file as avakar showed.

    0 讨论(0)
  • 2020-12-11 06:08

    The "STL way" is to use copy_n, which is in the STL but not the C++ standard.

    0 讨论(0)
提交回复
热议问题