继承 ostream 和 xsputn 和 Overflow 的 Streambuf 问题
inheriting ostream and streambuf problem with xsputn and overflow
我一直在研究创建自己的ostream,以及一个streambuf来处理我的ostream的缓冲区。 我实际上大部分工作,我可以将 (<<( 插入到我的流中并毫无问题地获取字符串。 我通过暗示虚拟函数xsputn来做到这一点。 但是,如果我在流中输入 (<<( 浮点数或整数而不是字符串 xsputn 永远不会被调用。
我已经浏览了代码,我看到流正在调用do_put,然后f_put最终尝试将浮点数 1 个字符一次放入缓冲区。 如果我离开没有空间的缓冲区,我可以让它调用我的虚拟函数溢出(int c(的实现,从而获取浮点数和整数的数据。
现在问题来了,我需要知道浮点何时完成放入缓冲区。 或者换句话说,我需要知道这是最后一次为正在流式传输的特定值调用溢出的时间。 xsputn 对我有用的原因是因为我预先获得了整个值及其长度。 所以我可以将其复制到缓冲区中,然后调用等待缓冲区已满的函数。
我承认滥用了 ostream 设计,因为我需要缓存输出,然后为每个输入值 (<<( 一次发送所有输出。
无论如何,为了清楚起见,我将以另一种方式重申我正在拍摄的内容。 很有可能我只是以错误的方式去做。
我想使用继承的 ostream 和 streambuf,以便我可以在其中输入值并允许它为我处理我的类型转换,然后我想将这些信息转移到另一个对象,我将句柄传递给 streambuf 到(for?(。 该对象具有昂贵的 I/O,所以我不想一次发送 1 个字符的数据。
如果不清楚,提前抱歉。 谢谢你的时间。
清楚你在做什么,尽管听起来很粗略右。 可以肯定的是:您的ostream
所做的只是提供方便构造函数创建和安装您的streambuf
,析构函数,可能还有 rdbuf
的实现处理正确类型的缓冲区。 假设这是真的:在streambuf
中定义xsputn
纯粹是一种优化。您必须定义的关键功能是 overflow
. 最简单的overflow
的实现只需要一个字符,并且将其输出到接收器。 除此之外的一切都是优化:例如,您可以使用setp
设置缓冲区;如果你这样做this,则overflow
只有当缓冲区已满,或请求刷新。 在这种情况下,您必须输出缓冲区(使用 pbase
和 pptr
来获取地址(。 (streambuf
基类初始化用于创建 0 长度缓冲区的指针,因此overflow
将是要求每个字符。 您可能使用的其他功能想要在(非常(特定的情况下覆盖:
imbue
:如果出于某种原因需要区域设置。 (请记住当前字符编码是区域设置的一部分。
setbuf
:允许客户端代码指定缓冲区。 (恕我直言,这是通常不值得打扰,但您可能有特别的要求。
seekoff
: 支持寻找。 我从未在任何我的streambuf
,所以我不能提供任何超出的信息您可以在标准中阅读。
sync
:刷新时调用,应输出缓冲到接收器。 如果您从不打电话给setp
(所以没有缓冲区(,您始终处于同步状态,这可能是无操作。 overflow
或uflow
可以调用此一个,或者两者都可以调用一些独立功能。 (关于sync
之间的唯一区别uflow
是,只有在有以下情况下才会调用uflow
一个缓冲区,如果缓冲区为空,则永远不会调用它。 如果客户端代码刷新流,将调用sync
。
编写自己的流时,除非性能要求否则,我将保持简单,只覆盖overflow
.如果性能决定了缓冲区,我通常会将代码放入将缓冲区冲洗到单独的write(address, length)
功能,并沿线实施overflow
和sync
之:
int MyStreambuf::overflow( int ch )
{
if ( pbase() == NULL ) {
// save one char for next overflow:
setp( buffer, buffer + bufferSize - 1 );
if ( ch != EOF ) {
ch = sputc( ch );
} else {
ch = 0;
}
} else {
char* end = pptr();
if ( ch != EOF ) {
*end ++ = ch;
}
if ( write( pbase(), end - pbase() ) == failed ) {
ch = EOF;
} else if ( ch == EOF ) {
ch = 0;
}
setp( buffer, buffer + bufferSize - 1 );
}
return ch;
}
int sync()
{
return (pptr() == pbase()
|| write( pbase(), pptr() - pbase() ) != failed)
? 0
: -1;
}
一般来说,我不会打扰xsputn
,但如果你的客户代码输出了很多长字符串,这可能很有用。像这样的东西应该可以解决问题:
streamsize xsputn(char const* p, streamsize n)
{
streamsize results = 0;
if ( pptr() == pbase()
|| write( pbase(), pptr() - pbase() ) != failed ) {
if ( write(p, n) != failed ) {
results = n;
}
}
setp( buffer, buffer + bufferSize - 1 );
return results;
}
- 警告处理为错误这里有什么问题
- 最小硬币更换问题(自上而下方法)
- 为"adjacent"变量赋值时出现问题
- 我的神经网络不起作用 [XOR 问题]
- 在Ubuntu 16.04上安装Cilk时出现问题
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 编译包含字符串的代码时遇到问题
- Project Euler问题4的错误解决方案
- 问题:什么是QAbstractItemView::NoEditTriggers的反面
- 在编译C++代码(具有dlib和opencv)到WASM时面临问题
- 在进程中对同一管道进行读取和写入时C++管道出现问题
- 静态数据成员的问题-修复链接错误会导致编译器错误
- C++ 雷神库 - 使用资源加载器类时出现问题(不命名类型)
- 一个关于在C++中重载布尔运算符的问题
- 首要问题的答案让值班员搞错了
- setlocale的C++土耳其字符串问题
- 如何重构类层次结构以避免菱形问题
- 基于boost的程序的静态链接——zlib问题
- 为gzipped流编写自定义streambuf的问题
- 继承 ostream 和 xsputn 和 Overflow 的 Streambuf 问题