#include <strstream.h> // includes <iostream.h> class strstreambuf : public streambuf { public: strstreambuf(); strstreambuf(int n); strstreambuf(void* (*a)(long), void (*f)(void*)); strstreambuf(char* _s, int, char* _strt=0); ~strstreambuf();
void freeze_unlocked(int = 1); void freeze(int = 1); char* str_unlocked(); char* str(); virtual int doallocate(); virtual int overflow(int); virtual int underflow(); virtual streambuf* setbuf(char*, int); virtual streampos seekoff(streamoff, unsafe_ios::seek_dir, int); };
strstreambuf 类是 streambuf 的特例,使用 char 数组(字符串)作为字符的来源或目的地。将从数组中获取(输入)字符并且字符将由数组使用(写入到其中)。sbufprot3CC4() 和 sbufpub3CC4() 中描述了基本的 streambuf 操作。get 和 put 指针指向附加的数组中,并且移动 get 或 put 指针相当于递增或递减 char*。
为使 streambuf 实现多线程安全,也就是说,能够在多线程环境中正确工作,在每个公共成员函数中都使用了锁。引入了一组无锁的备选公共成员函数以在对性能要求极高的单线程应用程序中使用。这些成员函数与原始函数共享相同的名称,但是附加了后缀 _unlocked。除了是多线程安全的之外,这些成员函数具有完全相同的功能。有关更多信息,请参见《C++ 4.1 Library Reference Manual》中的第 5 章 "Using libC in a Multithreaded Environment"。
strstreambuf 可以通过以下两种模式之一使用:动态或静态。在动态模式下,将自动分配数组并根据需要对其进行扩展以容纳任何长度的字符串。当需要更多空间时,会分配一个新的保留区并将旧数组中的数据复制到其中,然后删除旧数组。在静态模式下,将使用用户提供的固定数组,固定数组无法移动也无法更改为新缓冲区,它从不会被动态删除。可以冻结动态 strstreambuf,也就是说,使其不可扩展。可以将冻结的或静态 strstreambuf 转换为 char* 以在需要 C 样式字符串的表达式中使用。可以解冻冻结的动态 strstreambuf:使其重新成为可扩展的。
构造一个空的、动态的未冻结 strstreambuf。将根据需要自动分配字符串的空间。如果您知道将插入某个最小数目的字符,则应当使用 strstream(int) 构造函数或使用 setbuf() 创建缓冲区(请参见下文)以避免重复分配和取消分配小型数组。
构造一个空的、动态的未冻结 strstreambuf,且初始缓冲区大小至少为 n 字节。
构造一个空的、动态的未冻结 strstreambuf。将根据需要自动分配字符串的空间。不使用 new 和 delete,而是调用所提供的函数 alloc 和 del。函数 alloc 必须接受一个 long 参数,即要分配的字节数;它必须返回所分配空间的指针(类型为 void*),或者在失败时返回零。如果 alloc 为空,则将使用 new。函数 del 必须接受一个 void* 类型的参数,这将是从 alloc 获得的指针值;其返回类型为 void。如果 del 为空,则将使用 delete。使用此构造函数时必须小心,alloc 和 del 是兼容的。
使用 ptr 指向的缓冲区构造一个静态 strstreambuf。如果 len 为正数并且 putp 为空,则会使用从 ptr 开头的 len 个字节。如果 putp 不为空,则会忽略 len,并且初始获取区将从 ptr 运行到 putp。如果 len 为零,则会假定 ptr 指向以空字符结束的字符串,并且将使用直到但不包括空字节的区域作为缓冲区。如果 len 为负数,则会假定缓冲区的长度不受限;很明显,这可能是一种危险模式。get 指针最初将设置为 ptr。put 指针最初将设置为 putp。如果 putp 为空,则会将存储视为错误。
示例:
strstreambuf greeting("Hello, world!", 0, 0);
创建一个包括所提供的文本的缓冲区。数据不可被覆盖或扩展。
char *hi = "Hello, world!"; strstreambuf greeting(hi, 0, hi+7);
创建一个包括所提供的文本的缓冲区。从 'w' 到 '!',数据可以被覆盖,但不可扩展。
char *hi = "Hello, world!"; strstreambuf greeting(hi, 5, hi);
创建一个包括所提供的文本的缓冲区。数据的 "Hello" 部分可以被读取或覆盖;缓冲区的其余部分不可访问。
如果 i 为非零值,则会冻结动态缓冲区;如果为零,则它会解冻缓冲区。冻结会阻止自动删除缓冲区,即使是销毁 strstreambuf 时也是如此。它还会阻止缓冲区扩展超出其当前大小。您将希望冻结缓冲区以允许接受指向它的指针,这将保持可靠,直至显式解冻缓冲区。一旦解冻,动态缓冲区可以自动扩展和删除。对于静态缓冲区,冻结无关紧要,因为它从不会自动扩展或删除。冻结不会使缓冲区以空字符结尾。
冻结 ssbuf 并返回指向缓冲区开头的指针。如果 ssbuf 处于动态模式但是缓冲区为空,则返回的指针可能为空。
如果 ptr 不为空,则会忽略请求;无法替换任何静态或动态 strstreambuf 的缓冲区。如果 ptr 为空,则会保存 len 的值,并且下一次动态模式分配将至少为 len 个字节。(这仅应用于下一次分配,然后将丢弃 len 的值。)您将希望使用此函数在缓冲区打算扩展时强制实施适当的大型分配,从而避免潜在的大量小型分配和取消分配序列。
ios (3CC4) 、 ios.intro (3CC4) 、 sbufprot (3CC4) 、 sbufpub (3CC4) 、 strstream (3CC4)
《C++ Library Reference》中的第 3 章 "The Classic iostream Library" 和第 4 章 "Using Classic iostreams in a Multithreaded Environment"。