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

ความแตกต่างระหว่าง getc(), getchar(), getch() และ getche() ใน C

ฟังก์ชันทั้ง 4 ตัวใช้สำหรับอ่านตัวอักษร (character) จาก input stream แต่มีพฤติกรรมต่างกันในเรื่อง buffering, echo, และ portability

สรุปความแตกต่างแบบเร็ว

Function Header Input Source Buffering Echo (แสดงบนหน้าจอ) Portability Return
getc() <stdio.h> FILE* stream ใดๆ (stdin, file, etc.) Buffered ไม่แสดง Standard C (ANSI/ISO) int (char หรือ EOF)
getchar() <stdio.h> stdin เท่านั้น (macro: getc(stdin)) Buffered ไม่แสดง Standard C (ANSI/ISO) int (char หรือ EOF)
getch() <conio.h> stdin (console) Unbuffered (no Enter needed) ไม่แสดง Non-standard (DOS/Windows: conio.h) int (char)
getche() <conio.h> stdin (console) Unbuffered (no Enter needed) แสดง (echo) Non-standard (DOS/Windows: conio.h) int (char)

รายละเอียดแต่ละฟังก์ชัน

getc(FILE *stream)

  • Standard C library function
  • อ่าน 1 character จาก stream ใดๆ ก็ได้
  • Buffered: ต้องกด Enter ก่อน (line buffered stdin)
  • คืนค่า int - character ที่อ่านได้ หรือ EOF (-1) ถ้า error/EOF
  • ใช้กับ file I/O ได้: getc(fp)

getchar()

  • Macro/Function เทียบเท่า getc(stdin)
  • อ่านจาก standard input เท่านั้น
  • Buffered: ต้องกด Enter
  • Standard C - portable

getch()

  • Non-standard: อยู่ใน <conio.h> (Console I/O - Borland/Turbo C, MSVC)
  • Unbuffered: อ่านทันทีที่กดปุ่ม ไม่ต้องกด Enter
  • No echo: ไม่แสดงตัวอักษรบนหน้าจอ
  • ใช้สำหรับ: Password input, Game controls, Menu navigation
  • ไม่มีใน Linux/Unix standard library (ใช้ termios หรือ ncurses แทน)

getche()

  • เหมือน getch() แต่ มี echo (แสดงตัวอักษรที่กด)
  • ยังคง non-standard, Windows-only

ตัวอย่างโค้ด (Windows + conio.h)

#include 
#include   // Windows only!

int main() {
    char c1, c2, c3, c4;
    
    printf("Test getc(stdin): Type a char + Enter: ");
    c1 = getc(stdin);
    printf("You typed: %c\n", c1);
    
    printf("Test getchar(): Type a char + Enter: ");
    c2 = getchar();
    printf("You typed: %c\n", c2);
    
    printf("Test getch(): Press any key (no echo): ");
    c3 = getch();  // ไม่ต้องกด Enter, ไม่แสดงตัวอักษร
    printf("\nYou typed: %c\n", c3);
    
    printf("Test getche(): Press any key (with echo): ");
    c4 = getche(); // ไม่ต้องกด Enter, แสดงตัวอักษร
    printf("\nYou typed: %c\n", c4);
    
    return 0;
}

Output (ตัวอย่าง)

Test getc(stdin): Type a char + Enter: A
You typed: A
Test getchar(): Type a char + Enter: B
You typed: B
Test getch(): Press any key (no echo): 
You typed: C
Test getche(): Press any key (with echo): D
You typed: D

Cross-platform Alternatives (Linux/Unix/macOS)

บน Linux/Unix ไม่มี conio.h ใช้วิธีอื่นแทน:

1. ใช้ termios (Linux/Unix) - Non-blocking single char

#include 
#include 
#include 

int getch_unix() {
    struct termios oldt, newt;
    int ch;
    tcgetattr(STDIN_FILENO, &oldt);
    newt = oldt;
    newt.c_lflag &= ~(ICANON | ECHO);  // Disable canonical mode & echo
    tcsetattr(STDIN_FILENO, TCSANOW, &newt);
    ch = getchar();
    tcsetattr(STDIN_FILENO, TCSANOW, &oldt);  // Restore
    return ch;
}

int getche_unix() {
    struct termios oldt, newt;
    int ch;
    tcgetattr(STDIN_FILENO, &oldt);
    newt = oldt;
    newt.c_lflag &= ~ICANON;  // Disable canonical only (keep echo)
    tcsetattr(STDIN_FILENO, TCSANOW, &newt);
    ch = getchar();
    tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
    return ch;
}

2. ใช้ ncurses library (Portable)

#include 

int main() {
    initscr();      // Initialize ncurses
    cbreak();       // Disable line buffering
    noecho();       // Disable echo (like getch)
    // echo();       // Enable echo (like getche)
    
    int ch = getch();  // ncurses getch
    printw("You typed: %c\n", ch);
    refresh();
    getch();  // Wait for key
    endwin(); // Cleanup
    return 0;
}
// Compile: gcc -o demo demo.c -lncurses

3. Java/C#/Python equivalents

Language getch() equivalent getche() equivalent
Java Console.readPassword() (no echo), System.in.read() (blocking) Scanner, Console.readLine()
C# Console.ReadKey(true).KeyChar Console.ReadKey(false).KeyChar
Python msvcrt.getch() (Windows), getch library (Unix) msvcrt.getche() (Windows)

Best Practices

  • Portable code: ใช้ getchar() หรือ getc(stdin) เท่านั้น
  • Password input: ใช้ platform-specific (getch/conio หรือ termios/ncurses)
  • Interactive CLI: ใช้ library เหมาะสม: ncurses (C), jline (Java), prompt-toolkit (Python)
  • Don't mix: อย่าใช้ getc/getchar ควบคู่กับ getch/getche ในโปรแกรมเดียว (buffering conflict)

หมายเหตุสำคัญ

  • getch() และ getche() เป็น legacy DOS/Windows functions ไม่ใช่ส่วนหนึ่งของ C Standard
  • ใน Visual Studio ใหม่ ให้ define _CRT_SECURE_NO_WARNINGS หรือใช้ _getch(), _getche() แทน
  • สำหรับ competitive programming บน Windows มักใช้ getchar() หรือ scanf แทน เพื่อ portability