ungetc
ヘッダ <stdio.h> で定義 | ||
int ungetc(int ch, FILE*stream ); | ||
ch
が EOF と等しくなければ、 (unsignedchar として再解釈された) 文字 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(constchar* fmt, FILE* s){if(*fmt =='%'){int c;switch(*++fmt){case'u':while(isspace(c=getc(s))){}// skip leading white spaceunsignedint 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-digitcase'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'