ฟังก์ชันทั้ง 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