Namespaces
Variants

std:: ungetc

From cppreference.net
< cpp ‎ | io ‎ | c
ヘッダーで定義 <cstdio>
int ungetc ( int ch, std:: FILE * stream ) ;

ch EOF と等しくない場合、文字 ch unsigned char として再解釈し、ストリーム stream に関連付けられた入力バッファにプッシュします。これにより、後続の stream からの読み取り操作でその文字が取得されます。ストリームに関連付けられた外部デバイスは変更されません。

ストリームの再位置付け操作 std::fseek std::fsetpos 、および std::rewind ungetc の効果を破棄します。

ungetc が複数回呼び出され、その間に読み取りや再位置指定が行われない場合、失敗する可能性があります(言い換えれば、サイズ1のプッシュバックバッファは保証されますが、それ以上の大きさのバッファは実装定義です)。複数回の ungetc が成功した場合、読み取り操作は ungetc が行われた逆順でプッシュバックされた文字を取得します。

ch EOF と等しい場合、操作は失敗し、ストリームは影響を受けません。

ungetc の呼び出しが成功すると、 ファイル終端ステータスフラグ std::feof がクリアされます。

バイナリストリームに対する ungetc の成功した呼び出しは、ストリーム位置指示子を1つ減らします(ストリーム位置指示子がゼロだった場合の動作は未定義です)。

テキストストリームに対する ungetc の成功した呼び出しは、ストリーム位置指示子を未規定の方法で変更しますが、プッシュバックされたすべての文字が読み取り操作で取得された後、ストリーム位置指示子が ungetc 実行前の値と等しくなることを保証します。

目次

パラメータ

ch - 入力ストリームバッファにプッシュする文字
stream - 文字を戻すファイルストリーム

戻り値

成功時には ch が返されます。

失敗時には EOF が返され、指定されたストリームは変更されません。

注記

pushbackバッファのサイズは実際には4k(Linux、MacOS)から最小4(Solaris)、あるいは保証された最小値1(HPUX、AIX)まで様々です。

プッシュバックバッファの見かけ上のサイズは、プッシュバックされた文字が外部文字シーケンス内のその位置に存在する文字と等しい場合、より大きくなる可能性があります(実装は単に読み取りファイル位置インジケータをデクリメントし、プッシュバックバッファの維持を回避する可能性があります)。

std::ungetc の本来の目的での使用例を示します: std::scanf の実装

#include <cctype>
#include <cstdio>
void demo_scanf(const char* fmt, std::FILE* s)
{
    while (*fmt != '\0') {
        if (*fmt == '%') {
            switch (*++fmt) {
                case 'u': {
                    int c{};
                    while (std::isspace(c=std::getc(s))) {}
                    unsigned int num{};
                    while (std::isdigit(c)) {
                        num = num*10 + c-'0';
                        c = std::getc(s);
                    }
                    std::printf("%%u scanned %u\n", num);
                    std::ungetc(c, s);
                    break;
                }
                case 'c': {
                    int c = std::getc(s);
                    std::printf("%%c scanned '%c'\n", c);
                    break;
                }
            }
        } else {
            ++fmt;
        }
    }
}
int main()
{
    if (std::FILE* f = std::fopen("input.txt", "w+")) {
        std::fputs("123x", f);
        std::rewind(f);
        demo_scanf("%u%c", f);
        std::fclose(f);
    }
}

出力:

%u scanned 123
%c scanned 'x'

関連項目

ファイルストリームから文字を取得する
(関数)