문제

스트림 버퍼를 구현하려고 노력하고 있으며 만드는 데 어려움이 있습니다. overflow() 일하다. 버퍼를 10 자로 크기를 조정하고 사용 버퍼를 재설정합니다. setp. 그런 다음 우리가 중단 한 곳에서 포인터를 다시 늘립니다. 어떤 이유로 든 출력이 옳지 않습니다.

template <class charT, class traits = std::char_traits<charT>>
class stringbuf : public std::basic_stringbuf<charT, traits>
{
public:
    using char_type   = charT;
    using traits_type = traits;
    using int_type    = typename traits::int_type;
public:
    stringbuf()
        : buffer(10, 0)
    {
        this->setp(&buffer.front(), &buffer.back());
    }

    int_type overflow(int_type c = traits::eof())
    {
        if (traits::eq_int_type(c, traits::eof()))
            return traits::not_eof(c);

        std::ptrdiff_t diff = this->pptr() - this->pbase();

        buffer.resize(buffer.size() + 10);
        this->setp(&buffer.front(), &buffer.back());

        this->pbump(diff);

        return traits::not_eof(traits::to_int_type(*this->pptr()));
    }
    // ...
    std::basic_string<charT> str()
    {
        return buffer;
    }
private:
    std::basic_string<charT> buffer;
};

int main()
{
    stringbuf<char> buf;
    std::ostream os(&buf);

    os << "hello world how are you?";
    std::cout << buf.str();
}

문자열을 인쇄하면 다음과 같이 나옵니다.

안녕하세요 Worl ou는 어떻습니까?

누락되었습니다 d 그리고 y. 내가 뭘 잘못 했어?

도움이 되었습니까?

해결책

가장 먼저하지 않는 것은 당신이 std::basic_stringbuf<char> 모든 관련 가상 기능을 무시하지 않고 어떤 이유로 든. 예를 들어, 당신은 무시하지 않습니다 xsputn() 또는 sync(): 이러한 기능이 무엇이든간에 물려받을 수 있습니다. 스트림 버퍼를 파생하는 것이 좋습니다 std::basic_streambuf<char> 대신에!

그만큼 overflow() 메소드는 스트림 버퍼에 문자열보다 작은 하나의 문자 인 버퍼를 발표합니다. &buffer.back() 배열 끝에 대한 포인터가 아니라 문자열의 마지막 문자에 대한 포인터입니다. 개인적으로 나는 사용할 것입니다

this->setp(&this->buffer.front(), &this->buffer.front() + this->buffer.size());

지금까지 문제가 없습니다. 그러나 더 많은 캐릭터를위한 공간을 마련한 후에는 넘치는 캐릭터를 추가하여 생략했습니다. 즉, 논쟁은 전달되었습니다. overflow() 버퍼에 :

this->pbump(diff);
*this->pptr() = traits::to_char_type(c);
this->pbump(1);

옳지 않은 몇 가지 작은 것들이 더 있습니다.

  1. 일반적으로 무시하는 것은 나쁜 생각입니다 virtual 기능 기본 매개 변수입니다. 기본 클래스 함수는 이미 기본값을 제공하며 함수가 명시 적으로 호출 될 때만 새 기본값을 선택합니다.
  2. 반환 된 문자열에는 버퍼가 정확히 가득 차 있지 않는 한 지금까지 서열보다 더 크기 때문에 반환 된 문자열에는 끝에 여러 널 문자가 포함될 수 있습니다. 당신은 아마도 그것을 구현해야합니다 str() 다르게 기능 :

    std::basic_string<charT> str() const
    {
        return this->buffer.substr(0, this->pptr() - this->pbase());
    }
    
  3. 일정한 가치로 문자열을 키우는 것은 주요 성능 문제입니다 : 글쓰기 비용 n 캐릭터입니다 n * n. 더 큰 경우 n (실제로 거대해질 필요는 없습니다) 이것은 문제를 일으킬 것입니다. 당신은 당신의 성장을 훨씬 낫습니다 buffer 기하 급수적으로, 예를 들어, 매번 배가되거나 1.5 두 배가된다고 느끼면 좋은 생각이 아닙니다.
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top