zoukankan      html  css  js  c++  java
  • 【C++ IO机制】stream_buf 解析

    stream_buf 解析

    1. stream_buf原型:

    template <class CharT, class Traits = std::char_traits<CharT>>
    class basic_streambuf;

    【注意】

    typedef basic_streambuf<char> streambuf;

    用于输出的 streambuf

    streambuf 使用三个指针来管理相应的输出缓冲区(缓冲区需要自行设置),分别由接口 pbasepptr和 epptr 返回。其中 pbase 是缓冲区的基指针,指向缓冲区的第一个字节,epptr 是缓冲区的尾指针,指向其最后一个字节的下一个字节(类似于 iter.end() 的作用),而 pptr 指向缓冲区当前可用的位置,也就是pptr 之前都已经被数据所填充,如下图:

     streambuf 定义的输出相关的函数主要有 sputc 和 sputn,前者输出一个字符到缓冲区,并且将指针 pptr 向后移动一个字符,后者调用函数 xsputn 连续输出多个字符,xsputn 默认的实现就是多次调用 sputc。由于缓冲区有限,当 pptr 指针向后移动满足 pptr() == epptr 时,说明缓冲区满了,这时将会调用函数 overflow 将数据写入到外部设备并清空缓冲区;清空缓冲区的方式则是调用 pbump 函数将指针 pptr 重置。我们可以通过如下的类来实现自定义的输出 buffer:

    用于输入的 streambuf

    同管理输出缓冲区一样,streambuf 也使用三个指针,eback()gptr() 以及 egptr() 分别指示输入缓冲区的开始字节,当前可用字节以及缓冲区尾的下一字节,如下图所示:

    streambuf 类同样定义了如下几个函数来支持对于输入缓冲区的读取和管理:

    • sgetc: 从输入缓冲区中读取一个字符;
    • sbumpc: 从输入缓冲区中读取一个字符,并将 gptr() 指针向后移动一个位置;
    • sgetn: 从输入缓冲区中读取 n 个字符;
    • sungetc: 将缓冲区的 gptr() 指针向前移动一个位置;
    • sputbackc: 将一个读取到的字符重新放回到输入缓冲区中;

    与输出缓冲区不同的是,输入缓冲区需要额外提供 putback 操作,也就是将字符放回到输入缓冲区内。

     

    1. 示例
     1 #include <iostream>
     2 #include <fstream>
     3 
     4 int main()
     5 {
     6   std::ifstream ifs("test.txt");
     7   if (ifs.good())
     8   {
     9     std::streambuf *pbuf = ifs.rdbuf();
    10     char c;
    11     ifs >> c;
    12     std::streamsize size = pbuf->in_avail();
    13     std::cout << "first character in file: " << c << '\n';
    14     std::cout << size << " characters in buffer after it\n";
    15   }
    16   ifs.close();
    17 
    18   return 0;
    19 }

    说明: test.file 文件内容如下:

    this is test file!

    输出:

    first character in file: t
    18 characters in buffer after it
     1 #include <iostream>
     2 #include <sstream>
     3 
     4 int main()
     5 {
     6   std::stringstream stream("Hello, world");
     7   std::cout << "sgetc() returned '" << (char)stream.rdbuf()->sgetc() << "'\n";
     8   std::cout << "peek() returned '" << (char)stream.peek() << "'\n";
     9   std::cout << "get() returned '" << (char)stream.get() << "'\n";
    10 }

    输出:

    sgetc() returned 'H'
    peek() returned 'H'
    get() returned 'H'
    

    说明:

    sgetc() 返回当前位置的字符。
    sbumpc() 返回当前位置的字符,并将当前位置前进到下一个字符。
    snextc() 将当前位置前进到下一个字符并返回下一个字符。

    参考资料

    1. std::streambuf从示例到应用

    2. stream_buff 解析【cppreference.com】

    3. C/C++编程:流缓冲类std::basic_streambuf

  • 相关阅读:
    hdu 1005(找循环节)
    hdu 1452(因子和+逆元)
    hdu 1215(因子和)
    hdu 1492(约数的个数)
    hdu 2136(质数筛选+整数分解)
    HDU 1286 找新朋友
    HDU 2136 Largest prime factor
    HDU 1722 Cake
    HDU 1713 相遇周期
    HDU 2138 How many prime numbers
  • 原文地址:https://www.cnblogs.com/sunbines/p/15730390.html
Copyright © 2011-2022 走看看