从 const char* 创建一个 streambuf 没有 boost?

Create a streambuf from const char* WITHOUT boost?

提问人:Captain'Flam 提问时间:1/11/2022 更新时间:1/11/2022 访问量:547

问:

从 const char* 创建 streambuf 相同的问题,只是我不能使用 boost

我必须实现一个将 a 作为输入参数的函数,为此,我必须调用另一个将 a 作为输入参数的函数。const char *istream

下面是一个非常简化的代码示例:

#include <iostream>
#include <string>
using namespace std ;

void inner_function_I_cant_change ( istream & input ) // the function I must use
    {
    string s ; // dummy implementation
    input >> s ;
    cout << s.size() << " : <" << s << ">" << endl ;
    }

struct externbuf : streambuf // my own streambuf using a char*...
    {
    int    size ;
    bool   done ;
    char * buffer ;

    externbuf ( const char * buffer , int size ) :
        size(size),
        done(false),
        buffer(const_cast<char*>( buffer )) {} // ...that forces me to an ugly const_cast !

    int underflow () 
        {
        if (this->gptr() == this->egptr()) 
            {
            if (done) return std::char_traits<char>::eof() ;
            this->setg( buffer,buffer,buffer+size ) ;
            done = true ;
            }
        return char_traits<char>::to_int_type( *this->gptr()) ;
        }
    };

void API_function_I_must_povide ( const char * data , int size ) // the function I must implement
    {
    externbuf buf( data,size ) ;
    istream   input( &buf ) ;
    inner_function_I_cant_change( input )  ;
    }

int main ()
    {
    API_function_I_must_povide( "bazinga!",8 ) ;
    }

这段代码我工作得很好,但我不得不做一个丑陋的!
我尝试使用 a 而不是 a,但我遇到了许多我不太理解的错误。
const_castbasic_streambuf<const char, char_traits<const char> >streambuf

有没有合适的方法可以做到这一点?
(而且,正如我所说,我不能使用助推器
)

谢谢!

C++ stl 常量转换 streambuf

评论

0赞 Remy Lebeau 1/11/2022
如果必须用于输入,那么你就无法避免 since 根本不接受 ,只有 .但是,在您的代码中,我会更改为 ,并将 移至调用。也就是说,你根本不需要,请参阅这个char_array_buffer,这是一个只读的 without or .const char*const_caststreambuf::setg()const char*char*bufferconst char*const_castsetg()setg()streambufconst char*setg()const_cast
0赞 Pete Becker 1/11/2022
不要重新发明轮子。std::istringstream 就是您所需要的。.std::string str(data, size); std::istringstream stream(str); inner_function_I_cant_change(stream);

答:

0赞 Captain'Flam 1/11/2022 #1

谢谢 Remy,你的 Art Of Code 链接让我很开心!

所以,对于那些感兴趣的人,这里是我的新代码,没有memcpy和丑陋const_cast


#include <iostream>
#include <string>
using namespace std ;

void inner_function_I_cant_change ( istream & input )
    {
    char buffer [1000] ;
    input.read( buffer,sizeof buffer ) ;
    string s1( buffer,input.gcount()) ;
    string s2( "hello \0 world !",15 ) ;
    if (s1 == s2) 
        cout << "success!" ;
    }

struct externbuf : public streambuf 
    {
    externbuf ( const char * data , unsigned int len ) : begin(data),crt(data),end(data + len) {}

    int_type underflow ()
        {
        return crt == end ? traits_type::eof() : traits_type::to_int_type( *crt ) ;
        }
    int_type uflow ()
        {
        return crt == end ? traits_type::eof() : traits_type::to_int_type( *crt++ ) ;
        }
    int_type pbackfail ( int_type ch )
        {
        bool cond = crt == begin || (ch != traits_type::eof() && ch != crt[-1]) ;
        return cond ? traits_type::eof() : traits_type::to_int_type( *--crt ) ;
        }
    streamsize showmanyc ()
        {
        return end - crt ;
        }

    const char *begin,*crt,*end ;
    };

void API_function_I_must_povide ( const char * data , int size )
    {
    externbuf buf( data,size ) ; 
    istream input( &buf ) ;
    inner_function_I_cant_change( input )  ;
    }

int main ()
    {
    API_function_I_must_povide( "hello \0 world !",15 ) ;
    }

谢谢 Pete,您的解决方案无需开发,但恐怕它会从数据std::string 的内部缓冲区产生一个 memcpy。由于我的缓冲区可能非常大,我尽量避免它们。