ungetc
來自 cppreference.com
定義於標頭檔案 <stdio.h> |
||
int ungetc( int ch, FILE* stream ); |
||
如果 ch 不等於 EOF,則將字元 ch(重新解釋為 unsigned char)推入與流 stream 關聯的輸入緩衝區中,使得後續對 stream 的讀取操作將檢索該字元。與流關聯的外部裝置不被修改。
流重新定位操作 fseek、fsetpos 和 rewind 會丟棄 ungetc
的效果。
如果在沒有中間讀取或重新定位的情況下多次呼叫 ungetc
,它可能會失敗(換句話說,保證大小為 1 的回推緩衝區,但任何更大的緩衝區都是實現定義的)。如果執行了多次成功的 ungetc
,則讀取操作將按 ungetc
的相反順序檢索回推字元。
如果 ch 等於 EOF,操作失敗,流不受影響。
對 ungetc
的成功呼叫會清除檔案結束狀態標誌 feof。
對二進位制流成功呼叫 ungetc
會使流位置指示器減一(如果流位置指示器為零,則行為不確定)。
對文字流成功呼叫 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) { while (*fmt != '\0') { if (*fmt == '%') { int c; switch (*++fmt) { case 'u': while (isspace(c=getc(s))) {} unsigned int num = 0; while (isdigit(c)) { num = num*10 + c-'0'; c = getc(s); } printf("%%u scanned %u\n", num); ungetc(c, s); break; case 'c': c = getc(s); printf("%%c scanned '%c'\n", c); break; } } else ++fmt; } } int main(void) { FILE* f = fopen("input.txt", "w+"); if (f != NULL) { fputs("123x", f); rewind(f); demo_scanf("%u%c", f); fclose(f); } return 0; }
輸出
%u scanned 123 %c scanned 'x'
[編輯] 參考
- C23 標準 (ISO/IEC 9899:2024)
- 7.21.7.10 The ungetc function (p: TBD)
- C17 標準 (ISO/IEC 9899:2018)
- 7.21.7.10 The ungetc function (p: 243)
- C11 標準 (ISO/IEC 9899:2011)
- 7.21.7.10 The ungetc function (p: 334)
- C99 標準 (ISO/IEC 9899:1999)
- 7.19.7.11 The ungetc function (p: 300)
- C89/C90 標準 (ISO/IEC 9899:1990)
- 4.9.7.11 The ungetc function
[編輯] 另請參閱
從檔案流中獲取一個字元 (function) | |
C++ documentation for ungetc
|