স্ট্রিং_ভিউ থেকে ডেটা অনুলিপি না করে স্ট্রিংস্ট্রিম তৈরি করার কোনও উপায় আছে কি?


10

আমি মনে করি এটি বেশ সোজা প্রশ্ন আমি বিশেষভাবে ব্যবহার করতে চাই std::get_timeতবে এটির সাথে কোনও প্রবাহের ব্যবহার করা দরকার। আমি একটিতে ডেটা পাস করছি string_viewএবং কেবল তারিখটি বিশ্লেষণের জন্য এটি অনুলিপি করা এড়াতে চাই।


1
আমি এখনই এটি দেখতে পাচ্ছি, সি ++ ২৩: std::basic_string_view_stream;-) এ এসে আপনি নিশ্চিত করতে পারবেন না আপনি অনুলিপি এড়াতে পারবেন কিনা। হয়তো হাওয়ার্ড কোন কৌশল জানতে পারবে।
নাথান অলিভার

2
দীর্ঘ-অবহেলিতরা এটি std::strstreamকরতে পারে।
ইগোর ট্যান্ডেটনিক

আমি এই সি ++ 14 কে ভুলভাবে ট্যাগ করেছি কারণ আমরা এই প্রকল্পে আছি। আমি আসলে ভুলে গেছি আমরা ব্যবহার করছি boost::string_view। যদিও প্রশ্নটি এখনও বৈধ।
বারটেক বানাচিউইচজ

উত্তর:


5

আপনি এটি বুস্ট.আইস্ট্রিস্টস লাইব্রেরির সাহায্যে সহজেই করতে পারেন:

#include <boost/iostreams/device/array.hpp>
#include <boost/iostreams/stream.hpp>

#include <iostream>
#include <string>

int main() {
    std::string_view buf{"hello\n"};
    boost::iostreams::stream<boost::iostreams::basic_array_source<char>> stream(buf.begin(), buf.size());

    std::string s;
    stream >> s;
    std::cout << s << '\n';
}

আপনি যে কাজ করতে দিয়ে সক্ষম হওয়া উচিত std::stringstreamএবং std::basic_stringbuf<CharT,Traits,Allocator>::setbufকিন্তু C ++ স্ট্যান্ডার্ডের তার প্রয়োজনীয়তা botched:

এর প্রভাব [এর setbuf] বাস্তবায়ন-সংজ্ঞায়িত: কিছু বাস্তবায়ন কিছুই করে না, আবার কিছু বাস্তবায়ন std::stringবর্তমানে সদস্য হিসাবে বাফার হিসাবে ব্যবহৃত সদস্যকে সাফ করে দেয় এবং ব্যবহারকারী দ্বারা সরবরাহ করা অক্ষরের অ্যারের ব্যবহার শুরু করে n, যার প্রথম উপাদানটি sবাফার হিসাবে চিহ্নিত করা হয় এবং ইনপুট / আউটপুট অক্ষর ক্রম।


1

বুস্ট.আইওস্ট্রিম ছাড়াই একটি বিকল্প সমাধান (যখন আপনি এটি ব্যবহার করতে পারবেন না)। এটি স্ট্যান্ড :: বেসিক_স্ট্রিউফ এবং স্ট্যান্ড :: বুনিয়াদী_প্রবাহের উপর ভিত্তি করে।

#include <cstring>
#include <iostream>
#include <istream>
#include <string_view>

template<typename __char_type, class __traits_type >
class view_streambuf final: public std::basic_streambuf<__char_type, __traits_type > {
private:
    typedef std::basic_streambuf<__char_type, __traits_type > super_type;
    typedef view_streambuf<__char_type, __traits_type> self_type;
public:

    /**
    *  These are standard types.  They permit a standardized way of
    *  referring to names of (or names dependent on) the template
    *  parameters, which are specific to the implementation.
    */
    typedef typename super_type::char_type char_type;
    typedef typename super_type::traits_type traits_type;
    typedef typename traits_type::int_type int_type;
    typedef typename traits_type::pos_type pos_type;
    typedef typename traits_type::off_type off_type;

    typedef typename std::basic_string_view<char_type, traits_type> source_view;

    view_streambuf(const source_view& src) noexcept:
      super_type(),
      src_( src )
    {
        char_type *buff = const_cast<char_type*>( src_.data() );
        this->setg( buff , buff, buff + src_.length() );
    }

    virtual std::streamsize xsgetn(char_type* __s, std::streamsize __n) override
    {
        if(0 == __n)
            return 0;
        if( (this->gptr() + __n) >= this->egptr() ) {
            __n =  this->egptr() - this->gptr();
            if(0 == __n && !traits_type::not_eof( this->underflow() ) )
                return -1;
        }
        std::memmove( static_cast<void*>(__s), this->gptr(), __n);
        this->gbump( static_cast<int>(__n) );
        return __n;
    }

    virtual int_type pbackfail(int_type __c) override
    {
        char_type *pos = this->gptr() - 1;
        *pos = traits_type::to_char_type( __c );
        this->pbump(-1);
        return 1;
    }

    virtual int_type underflow() override
    {
        return traits_type::eof();
    }

    virtual std::streamsize showmanyc() override
    {
        return static_cast<std::streamsize>( this->egptr() - this->gptr() );
    }

    virtual ~view_streambuf() override
    {}
private:
    const source_view& src_;
};

template<typename _char_type>
class view_istream final:public std::basic_istream<_char_type, std::char_traits<_char_type> > {
    view_istream(const view_istream&) = delete;
    view_istream& operator=(const view_istream&) = delete;
private:
    typedef std::basic_istream<_char_type, std::char_traits<_char_type> > super_type;
    typedef view_streambuf<_char_type, std::char_traits<_char_type> > streambuf_type;
public:
    typedef _char_type  char_type;
    typedef typename super_type::int_type int_type;
    typedef typename super_type::pos_type pos_type;
    typedef typename super_type::off_type off_type;
    typedef typename super_type::traits_type traits_type;
    typedef typename streambuf_type::source_view source_view;

    view_istream(const source_view& src):
        super_type( nullptr ),
        sb_(nullptr)
    {
        sb_ = new streambuf_type(src);
        this->init( sb_ );
    }


    view_istream(view_istream&& other) noexcept:
        super_type( std::forward<view_istream>(other) ),
        sb_( std::move( other.sb_ ) )
    {}

    view_istream& operator=(view_istream&& rhs) noexcept
    {
        view_istream( std::forward<view_istream>(rhs) ).swap( *this );
        return *this;
    }

    virtual ~view_istream() override {
        delete sb_;
    }

private:
    streambuf_type *sb_;
};


int main(int argc, const char** argv)
{
    std::string_view v("ABDCD\n 123\n FAG\n 456789");

    view_istream<char> in( v );

    std::string s;
    in >> s;
    std::cout << s << std::endl;

    int i;
    in >> i;
    std::cout << i << std::endl;

    in >> s;
    std::cout << s << std::endl;

    in >> i;
    std::cout << i << std::endl;

    return 0;
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.