Namespaces
Variants

std::basic_stringbuf<CharT,Traits,Allocator>:: underflow

From cppreference.net
protected :
virtual int_type underflow ( )

バッファの取得領域から次の文字を読み取ります。

具体的には:

1) 入力シーケンスに読み取り可能な位置がある場合( egptr ( ) > gptr ( ) )、 Traits :: to_int_type ( * gptr ( ) ) を返す
2) それ以外の場合、 pptr ( ) > egptr ( ) (前回 overflow() egptr() を変更してからストリームに文字が挿入された場合)であれば、get領域の終端を拡張して最新に挿入された文字を含めるように、 egptr() pptr() と等しく変更し、その後 Traits :: to_int_type ( * gptr ( ) ) を返します。
3) それ以外の場合、 Traits :: eof ( ) を返す。

バッファ内で初期化された任意の文字は、それがコンストラクタで渡された文字列に由来するか、 overflow() によって追加されたかに関わらず、入力シーケンスの一部と見なされます。

目次

パラメータ

(なし)

戻り値

Traits :: to_int_type ( * gptr ( ) ) (取得領域で次に読み込む文字)が成功した場合、または Traits :: eof ( ) が失敗した場合。

#include <iostream>
#include <sstream>
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)
    {
        std::cout << "Before overflow():  get area size is " << egptr() - eback()
                  << ", the put area size is " << epptr() - pbase() << '\n';
        int_type rc = std::stringbuf::overflow(c);
        std::cout << "After overflow():   get area size is " << egptr() - eback()
                  << ", put area size is " << epptr() - pbase() << '\n';
        return rc;
    }
    int_type underflow()
    {
        std::cout << "Before underflow(): get area size is " << egptr() - eback()
                  << ", put area size is " << epptr() - pbase() << '\n';
        int_type ch = std::stringbuf::underflow();
        std::cout << "After underflow():  get area size is " << egptr() - eback()
                  << ", put area size is " << epptr() - pbase() << '\n';
        if (ch == EOF)
            std::cout << "underflow() returns EOF\n";
        else
            std::cout << "underflow() returns '" << char(ch) << "'\n";
        return ch;
    }
};
int main()
{
    mybuf sbuf("123"); // 読み書きストリーム
    std::iostream stream(&sbuf);
    int n;
    stream >> n; // sgetc()を4回呼び出す
                 // 最初の3回の呼び出しは文字 '1', '2', '3' を返す
                 // 4回目の呼び出しで、gptr() == egptr() となり underflow() が呼び出される
                 // underflow は EOF を返す
    std::cout << "n = " << n << '\n';
    stream.clear(); // eofbit をクリア
    stream << "123456"; // sputc() が6回呼び出される
                        // 最初の3回の呼び出しは既存のバッファに "123" を格納
                        // 4回目の呼び出しで pptr() == epptr() となり overflow() を呼び出す
                        // overflow() はバッファを拡張し egptr() を4に設定
                        // 5回目と6回目の呼び出しは '5' と '6' を格納し、pptr() を進める
    stream >> n; // sgetc() を4回呼び出す
                 // 1回目の呼び出しは overflow() によって利用可能になった '4' を返す
                 // 2回目の呼び出しで、egptr() == egptr() となり underflow() が呼び出される
                 // underflow は egptr() を pptr() (6) に進める
                 // 3回目の sgetc() は '6' を返す
                 // 4回目の sgetc() は gptr() == egptr() を検出し、underflow() を呼び出す
                 // underflow() は EOF を返す
    std::cout << "n = " << n << '\n';
}

出力例:

Before underflow(): get area size is 3, put area size is 15
After underflow():  get area size is 3, put area size is 15
underflow() returns EOF
n = 123
Before underflow(): get area size is 3, put area size is 15
After underflow():  get area size is 6, put area size is 15
underflow() returns '4'
Before underflow(): get area size is 6, put area size is 15
After underflow():  get area size is 6, put area size is 15
underflow() returns EOF
n = 456

不具合報告

以下の動作変更の欠陥報告書は、以前に公開されたC++規格に対して遡及的に適用されました。

DR 適用対象 公開時の動作 正しい動作
LWG 432 C++98 overflow() によって追加された文字が入力シーケンスの一部と見なされるかどうかが不明確であった 明確化された

関連項目

[virtual]
関連付けられた入力シーケンスから文字を読み取り、取得領域に格納する
( std::basic_streambuf<CharT,Traits> の仮想保護メンバ関数)
[virtual]
関連付けられたファイルから読み取る
( std::basic_filebuf<CharT,Traits> の仮想保護メンバ関数)
[virtual]
次のポインタを進めずに入力シーケンスから文字を読み取る
( std::strstreambuf の仮想保護メンバ関数)
シーケンスを進めずに入力シーケンスから1文字読み取る
( std::basic_streambuf<CharT,Traits> の公開メンバ関数)