C++ binary file I/O to/from containers (other than char *) using STL algorithms

前端 未结 4 537
逝去的感伤
逝去的感伤 2021-01-06 22:52

I\'m attempting a simple test of binary file I/O using the STL copy algorithm to copy data to/from containers and a binary file. See below:

 1 #include 

        
4条回答
  •  没有蜡笔的小新
    2021-01-06 23:33

    To write binary data using std::copy().
    I would do this:

    template
    struct oi_t: public iterator
    {
      oi_t(std::ostream& str)
        :m_str(str)
      {}
      oi_t& operator++()   {return *this;}  // increment does not do anything.
      oi_t& operator++(int){return *this;}
      oi_t& operator*()    {return *this;}  // Dereference returns a reference to this
                                           // So that when the assignment is done we
                                           // actually write the data from this class
      oi_t& operator=(T const& data)
      {
        // Write the data in a binary format
        m_str.write(reinterpret_cast(&data),sizeof(T));
        return *this;
      }
    
      private:
        std::ostream&   m_str;
    };
    

    Thus the call to std::copy is:

    copy (vd.begin(), vd.end(), oi_t(output));
    

    The input iterator is slightly more complicated as we have to test for the end of the stream.

    template
    struct ii_t: public iterator
    {
      ii_t(std::istream& str)
        :m_str(&str)
      {}
      ii_t()
        :m_str(NULL)
      {}
      ii_t& operator++()   {return *this;}  // increment does nothing.
      ii_t& operator++(int){return *this;}
      T& operator*()
      {
        // On the de-reference we actuall read the data into a local //// static ////
        // Thus we can return a reference
        static T result;
        m_str->read(reinterpret_cast(&result),sizeof(T));
        return result;
      }
      // If either iterator has a NULL pointer then it is the end() of stream iterator.
      // Input iterators are only equal if they have read past the end of stream.
      bool operator!=(ii_t const& rhs)
      {
          bool lhsPastEnd  = (m_str == NULL)     || (!m_str->good());
          bool rhsPastEnd  = (rhs.m_str == NULL) || (!rhs.m_str->good());
    
          return !(lhsPastEnd && rhsPastEnd);
      } 
    
      private:
        std::istream*   m_str;
    };
    

    The call to read the input is now:

    ii_t ii(input);
    copy (ii, ii_t(), back_inserter(vi));
    

提交回复
热议问题