std::stringstream 是否有两个缓冲区,因此有两个标记?

问题描述

C++ 入门第 17 章; I/O 流;据说 std::iostream 类型的对象或 std::fstreamstd::stringstream 等派生类型支持读取和写入。这些类型也只有一个标记一个缓冲区:

fstreamstringstream 类型可以读取和写入相同的流。在这些类型中,有一个保存要读取和写入的数据的缓冲区和一个表示缓冲区中当前位置的标记。库将 gp 位置都映射到这个单个标记

为了了解更多,我完成了这个程序:

int main(){


    std::fstream fio("data.txt");
    std::cout << fio.tellg() << '\t' << fio.tellp() << '\n';
    fio.seekg(0,std::ios::end);
    std::cout << fio.tellg() << '\t' << fio.tellp() << '\n';

    std::stringstream ss("abcd\nefg\nhi\nj");
    std::cout << ss.tellg() << '\t' << ss.tellp() << '\n';
    ss.seekg(0,std::ios::end);
    std::cout << ss.tellg() << '\t' << ss.tellp() << '\n';

}

输出

 0      0
 14     14
 0      0
 13     0 
  • 正如您在使用 std::fstream 时所看到的,如果我使用 seekg() 移动读取标记,则 tellgtellp 返回相同的值。这太合乎逻辑了。

  • 但是,当移动 std::stringstream 的读取标记时,tellgtellp 返回不同的值,所以写入标记没有被移动?

  • 这是否意味着 std::stringstream 有两个缓冲区和两个标记?谢谢

解决方法

是的,这本书是错的。

同步读写位置的是std::basic_filebuf,并且,

类模板basic_fstream 在基于文件的流上实现高级输入/输出操作。它将基于文件的流缓冲区 (std::basic_filebuf) 与 (std::basic_iostream) 的高级接口连接起来。

然而,基类 std::basic_streambuf 确实维护单独的输入和输出缓冲区。请注意

I/O 流对象 std::basic_istream 和 std::basic_ostream 以及从它们派生的所有对象(std::ofstream、std::stringstream 等)都已实现完全按照std::basic_streambuf