ungetc
| ヘッダ <stdio.h> で定義
|
||
int ungetc( int ch, FILE *stream ); |
||
ch が EOF と等しくなければ、 (unsigned char として再解釈された) 文字 ch を、 stream からの後続の読み込み操作がその文字を受け取るように、ストリーム stream に紐付けられている入力バッファにプッシュします。 ストリームに紐付けられている外部デバイスは変更されません。
ストリームの位置を再設定する操作 fseek、 fsetpos および rewind は ungetc の効果を破棄します。
読み込みまたは位置の再設定を挟まずに ungetc が2回以上呼ばれた場合、 ungetc は失敗するかもしれません (別の言い方をすると、サイズ1のプッシュバックバッファは保証されていますが、それより大きいバッファは処理系定義です)。 複数回の ungetc に成功した場合、読み込み操作はプッシュバックされた文字を ungetc の逆順で取得します。
ch が EOF と等しい場合、操作は失敗し、ストリームは影響を受けません。
ungetc の呼び出しの成功は、ファイル終端状態フラグ feof をクリアします。
バイナリストリームに対する ungetc の呼び出しの成功は、ストリームの位置指示子を1デクリメントします (ストリームの位置指示子がゼロであった場合、動作は不定です)。
テキストストリームに対する ungetc の呼び出しの成功は、ストリームの位置指示子を未規定の方法で変更しますが、プッシュバックされた文字を読み込み操作ですべて取得した後、ストリームの位置指示子が ungetc 前の値と等しくなることは保証されます。
引数
| ch | - | 入力ストリームのバッファにプッシュされる文字 |
| stream | - | 文字を戻すファイルストリーム |
戻り値
成功した場合は ch が返されます。
失敗した場合は EOF が返され、指定されたストリームは変更されません。
ノート
プッシュバックバッファのサイズは、実際のところ、 4k (Linux, MacOS)、 4 (Solaris)、または保証されている最小の 1 (HPUX, AIX) まで、様々です。
プッシュバックされた文字が外部文字シーケンスのその位置にすでに存在する文字と等しい場合、プッシュバックバッファの見かけのサイズはもっと大きくなることがあります (処理系は単純に読み込みファイル位置指示子をデクリメントして、プッシュバックバッファの管理を回避するかもしれません)。
例
ungetc の元々の意図 (scanf の実装) をデモンストレーションします
#include <ctype.h>
#include <stdio.h>
void demo_scanf(const char* fmt, FILE* s) {
if(*fmt == '%') {
int c;
switch(*++fmt) {
case 'u': while(isspace(c=getc(s))) {} // skip leading white space
unsigned int num = 0;
while(isdigit(c)) {
num = num*10 + c-'0';
c = getc(s);
}
printf("%%u scanned %u\n", num);
ungetc(c, s); // reprocess the non-digit
case 'c': c = getc(s);
printf("%%c scanned '%c'\n", c);
}
}
}
int main(void)
{
FILE* f = fopen("input.txt", "w+");
fputs("123x", f);
rewind(f);
demo_scanf("%u%c", f);
fclose(f);
}
出力:
%u scanned 123
%c scanned 'x'