std::ungetc
| ヘッダ <cstdio>で定義 |
||
| int ungetc( int ch, std::FILE *stream ); |
||
ch が EOF でない場合、ストリーム stream に関連付けられた入力バッファに文字 ch(unsigned char として再解釈される)を、後続の stream からの読み込み操作でその文字が取得されるようにプッシュします。ストリームに関連付けられた外部デバイスは変更されません。
ストリームの再配置操作である std::fseek、std::fsetpos、および std::rewind は、ungetc の効果を破棄します。
読み込みまたは再配置を挟まずに ungetc が複数回呼び出された場合、失敗する可能性があります(つまり、サイズ 1 のプッシュバックバッファは保証されますが、それより大きいバッファは実装定義です)。複数の ungetc が成功した場合、読み込み操作はプッシュバックされた文字を ungetc と逆の順序で取得します。
ch が EOF の場合、操作は失敗し、ストリームは影響を受けません。
正常に呼び出された ungetc は、ファイルの終端状態フラグ std::feof をクリアします。
バイナリストリームに対して ungetc を正常に呼び出すと、ストリーム位置指示子が 1 つ減少します(ストリーム位置指示子がゼロだった場合の動作は不定です)。
テキストストリームに対して ungetc を正常に呼び出すと、ストリーム位置指示子は不定な方法で変更されますが、プッシュバックされたすべての文字が読み込み操作で取得された後、ストリーム位置指示子は ungetc 呼び出し前の値と等しくなることが保証されます。
目次 |
[編集] パラメータ
| 文字 | - | 入力ストリームバッファにプッシュする文字 |
| stream | - | 文字を戻すファイルストリーム |
[編集] 戻り値
成功した場合、ch が返されます。
失敗した場合、EOF が返され、指定されたストリームは変更されません。
[編集] 注記
プッシュバックバッファのサイズは、実際には 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'
[編集] 関連項目
| ファイルストリームから1文字取得する (関数) | |
| C言語のドキュメント ungetc
| |