стандартный шаблон С++ 11 (STL) (std::basic_stringbuf) (5)

Определяется в заголовочном файле <sstream>
шаблон<

    класс CharT,
    класс Traits = std::char_traits<CharT>,
    класс Allocator = std::allocator<CharT>

> class basic_stringbuf : public std::basic_streambuf<CharT, Traits>

std::basic_stringbufпредставляет собой std::basic_streambuf, связанная с которым последовательность символов является произвольной последовательностью символов, которая находится в памяти. Его можно инициализировать из экземпляра std::basic_string или создать экземпляр этого класса.

std::basic_stringbufТипичная реализация хранит объект типа std::basic_string или эквивалентный контейнер масштабируемой последовательности в качестве члена данных и использует его как последовательность управляемых символов (массив из шести указателей на std::basic_streambuf ), так и связанный символ. последовательность (источник символов для всех операций ввода и цель для операций вывода).

Кроме того, типичные реализации поддерживают элемент данных типа std::ios_base::openmode для указания состояния потока (только чтение, только запись, чтение-запись, окончание-запись и т. д.).

Если overflow() использует стратегию распределения, может быть сохранен дополнительный указатель высшей точки для отслеживания последнего инициализированного символа. (начиная с С++ 11)

Также предусмотрены две специализации для распространенных типов персонажей:

тип определение
stringbuf basic_stringbuf<знак>
wstringbuf basic_stringbuf<wchar_t>


защищенная функция-член

Воспроизведение символов в выходной последовательности

std::basic_stringbuf<CharT,Traits,Allocator>::pbackfail

защищенный:
виртуальный int_type pbackfail( int_type c = Traits::eof() )

 Эта защищенная виртуальная функция вызывается общедоступными функциями basic_streambuf::sungetc и basic_streambuf::sputbackc (которые, в свою очередь, вызываются функциями basic_istream::unget и basic_istream::putback).

1) Вызывающий запрос запрашивает, чтобы область получения была подкреплена одним символом (вызов без аргументов или с Traits::eof() в качестве аргумента pbackfail())

а) Сначала проверьте, есть ли позиция воспроизведения, и завершите работу, если позиции воспроизведения нет (stringbuf не имеет внешней последовательности символов для повторного чтения)

б) Если вызывающая сторона ошибается, а позиция воспроизведения действительно доступна, просто уменьшите значение basic_streambuf::gptr(), например, чтобы вызвать gbump(-1).

2) Символ, который пытается воспроизвести вызывающий, отличается от предыдущего геттера (вызов с тем символом, который нужно воспроизвести pbackfail()), в данном случае

а) Во-первых, проверьте, есть ли позиция воспроизведения, и потерпите неудачу, если нет.

б) Затем проверьте, какие символы находятся в позиции перетаскивания. Если хранящийся там символ уже равен c, определяемому Traits::eq(to_char_type(c), gptr()[-1]), просто уменьшите значение basic_streambuf::gptr().

c) В противном случае произойдет сбой, если буфер был открыт только для чтения.

г) В противном случае, если буфер открыт для записи (режим && std::ios_base::out не равен нулю), уменьшите значение basic_streambuf::gptr() и запишите в место, на которое указывает скорректированный gptr() c.

параметр

с - возвращаемый символ или Traits::eof(), если требуется указать запасной вариант для области выборки

возвращаемое значение

c в случае успеха, за исключением cслучаев, когда Traits::eof() возвращает Traits::not_eof(c).

Traits::eof() при ошибке.

пример вызова

#include <sstream>
#include <string>
#include <iostream>

//  typedef basic_stringbuf<char> 	stringbuf;
struct mybuf : std::stringbuf
{
    mybuf(const std::string& new_str,
          std::ios_base::openmode which =
              std::ios_base::in | std::ios_base::out)
        : std::stringbuf(new_str, which) {}

    int_type pbackfail(int_type c) override
    {
        std::cout << "Before pbackfail(): get area size is "
                  << egptr() - eback() << ' '
                  << " put area size is "
                  << epptr() - pbase() << std::endl;

        int_type ch = std::stringbuf::pbackfail(c);

        std::cout << "After pbackfail(): get area size is "
                  << egptr() - eback() << ' '
                  << " put area size is "
                  << epptr() - pbase() << std::endl;

        if (ch == EOF)
        {
            std::cout << "pbackfail() returns EOF\n";
        }
        else
        {
            std::cout << "pbackfail() returns '"
                      << char(ch) << "'" << std::endl;
        }

        return ch;
    }
};

int main()
{
    mybuf sbuf("12345"); // 读写流

    sbuf.sungetc();
    std::cout << std::endl;
    sbuf.sputbackc('5');
    return 0;
}

выход

 

добавить символы к выходной последовательности

std::basic_stringbuf<CharT,Traits,Allocator>::overflow

защищено:
виртуальное переполнение типа int_type ( int_type c = Traits::eof() );

Добавить символы cк выходной последовательности символов.

Если cэто индикатор конца файла ( traits::eq_int_type(c,traits::eof()) == true ), символы не добавляются. Функция ничего не делает и возвращает неопределенное значение, отличное от traits::eof().

В противном случае, если выходная последовательность имеет доступное место для записи или если эта функция успешно сделала доступным место для записи, вызывается sputc(c) и возвращается c.

Если stringbuf открыт для вывода ( mode & ios_base::out) != 0 ), эта функция делает доступным место для записи: в этом случае она перераспределяет (или изначально выделяет) буфер, достаточно большой, чтобы вместить весь текущий буфер плюс не менее один персонаж. Если stringbuf также открыт для ввода ( (mode & ios_base::in) != 0 ), то overflowтакже увеличивается размер области получения, перемещая egptr() так, чтобы она указывала сразу за новой областью ввода.

параметр

с - персонаж для хранения в дропзоне

возвращаемое значение

При ошибке Traits::eof() указывает на ошибку. Если успешно добавлены символы, cто c. или при вызове с Traits::eof() в качестве аргумента какое-либо значение, отличное от Traits::eof().

Уведомление

Эта функция отличается от обычной overflow(), которая перемещает содержимое буфера в соответствующую последовательность символов, потому что буфер и связанная с ним последовательность std::basic_stringbuf являются одной и той же последовательностью.

пример вызова

#include <sstream>
#include <string>
#include <iostream>

//  typedef basic_stringbuf<char> 	stringbuf;
struct mybuf : std::stringbuf
{
    mybuf(const std::string& new_str,
          std::ios_base::openmode which =
              std::ios_base::in | std::ios_base::out)
        : std::stringbuf(new_str, which) {}

    int_type overflow(int_type c = EOF) override
    {
        std::cout << "stringbuf::overflow('"
                  << char(c) << "') called" << std::endl
                  << "Before: size of get area: "
                  << egptr() - eback() << std::endl
                  << "        size of put area: "
                  << epptr() - pbase() << std::endl;

        int_type ret = std::stringbuf::overflow(c);

        std::cout << "After : size of get area: "
                  << egptr() - eback() << std::endl
                  << "        size of put area: "
                  << epptr() - pbase() << std::endl;

        return ret;
    }
};

int main()
{
    std::cout << "read-write stream:" << std::endl;
    mybuf sbuf("   "); // 只读流
    std::iostream stream(&sbuf);
    stream << 1234;
    std::cout << sbuf.str() << std::endl;

    std::cout << std::endl << "read-only stream:" << std::endl;
    mybuf ro_buf("   ", std::ios_base::in); // 只读流
    std::iostream ro_stream(&ro_buf);
    ro_stream << 1234;

    std::cout << std::endl << "write-only stream:" << std::endl;
    mybuf wr_buf("   ", std::ios_base::out); // 只写流
    std::iostream wr_stream(&wr_buf);
    wr_stream << 1234;

    return 0;
}

 выход

 

Supongo que te gusta

Origin blog.csdn.net/qq_40788199/article/details/132257903
Recomendado
Clasificación