Определяется в заголовочном файле <sstream>
шаблон< класс CharT, |
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
защищенный: |
Эта защищенная виртуальная функция вызывается общедоступными функциями 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
защищено: |
Добавить символы 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;
}
выход