Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> การเขียนโปรแกรม C

ฟังก์ชัน ungetc() ใน C/C++: ส่งคืนตัวอักษรกลับ Stream

ฟังก์ชัน ungetc() ใช้ส่งคืนตัวอักษร (Push Back) กลับเข้า Input Stream เพื่อให้อ่านซ้ำได้ในครั้งถัดไป ทำงานกับ stdin, File Streams, และ Streams อื่นๆ อยู่ใน Header <stdio.h>

ไวยากรณ์

#include <stdio.h>
int ungetc(int c, FILE *stream);
  • c - ตัวอักษรที่จะส่งคืน (Converted to unsigned char)
  • stream - Input Stream (stdin, FILE*, etc.)
  • คืนค่า: ตัวอักษรที่ส่งคืน (Success), EOF (Failure)
  • รับประกัน: ส่งคืนได้ อย่างน้อย 1 ตัวอักษร ต่อ Stream (Standard Guarantee)

ตัวอย่าง: Push Back ตัวอักษร '0'

#include <stdio.h>

int main() {
    int c;
    
    // อ่านจนกว่าจะเจอ '0'
    while ((c = getchar()) != '0') {
        putchar(c);  // Echo ตัวอักษร
    }
    
    // เจอ '0' แล้ว - ส่งคืน '0' กลับ Stream
    ungetc(c, stdin);
    
    // อ่านใหม่ - จะได้ '0' อีกครั้ง
    c = getchar();
    putchar(c);
    
    puts("");
    printf("The End!");
    return 0;
}

ผลลัพธ์ (Input: s a b c t h 0)

s a b c t h 0
The End!

คำอธิบาย

  1. อ่านตัวอักษรทีละตัว จนกว่าจะเจอ '0'
  2. พิมพ์ตัวอักษรที่อ่านได้ (Echo)
  3. เมื่อเจอ '0' ให้ ungetc('0', stdin) ส่งคืน '0' กลับ Stream
  4. getchar() ครั้งถัดไป อ่านได้ '0' อีกครั้ง
  5. พิมพ์ '0' แล้วจบ

กรณีการใช้งานจริง (Use Cases)

1. Parser/Lexer: Lookahead 1 Character

int getToken(FILE *fp) {
    int c = fgetc(fp);
    if (c == '=') {
        int next = fgetc(fp);
        if (next == '=') return TOKEN_EQ;  // ==
        ungetc(next, fp);                   // Push Back
        return TOKEN_ASSIGN;                // =
    }
    // ...
}

2. จัดการ Number Parsing

double parseNumber(FILE *fp) {
    int c;
    double val = 0;
    while ((c = fgetc(fp)) != EOF && c >= '0' && c <= '9') {
        val = val * 10 + (c - '0');
    }
    if (c != EOF) ungetc(c, fp);  // Push Back Non-digit
    return val;
}

3. ทำให้ scanf() ทำงานถูกต้องหลังอ่านบางส่วน

int c = getchar();
if (c != 'Y' && c != 'y') {
    ungetc(c, stdin);  // Push Back ถ้าไม่ใช่ Y/y
    // scanf จะอ่านตัวนี้ได้อีกครั้ง
}

ข้อจำกัด (Limitations)

ฟังก์ชันเกี่ยวข้อง

  • ungetwc() - Wide Character Version (<wchar.h>)
  • fgetc(), getc(), getchar() - อ่านตัวอักษร
  • fseek(), ftell() - Random Access (สำหรับ Seekable Streams)

สรุป

ungetc() เป็นเครื่องมือสำคัญสำหรับ One-Character Lookahead ใน Parsers, Scanners, และ Input Processing ใช้งานง่าย แต่จำกัดที่ 1 Char Per Stream

ข้อจำกัดคำอธิบาย
Push Back ได้ 1 Char เท่านั้นStandard รับประกันแค่ 1 Char (บาง Implementation อาจมากกว่า)
ไม่ได้กับ Output Streamsใช้กับ Input Streams เท่านั้น
ไม่ได้กับ EOFไม่สามารถ ungetc(EOF, stream) ได้
ต้องอ่านก่อน Push Backไม่สามารถ Push Back ก่อนอ่านอะไรเลยได้
Binary Modeพฤติกรรมอาจแตกต่างไป (Implementation-defined)