ปัญหา
หลัง scanf("%d", &num) แล้ว ใช้ gets() หรือ scanf("%s", str) อ่าน String → **ข้ามการอ่าน String ไปเลย**
สาเหตุ
- User พิมพ์เลข เช่น
42แล้วกด Enter scanf("%d")อ่าน42แต่ **ทิ้ง\n(Newline) ไว้ใน Input Buffer**gets()/scanf("%s")อ่านเจอ\nทันที → คิดว่าเป็น String ว่าง → จบการอ่าน
วิธีแก้ไข
วิธีที่ 1: ใช้ scanf("%c") อ่านทิ้ง Newline (Quick Fix)
int num;
char name[50], dummy;
scanf("%d", &num);
scanf("%c", &dummy); // อ่าน \n ทิ้ง
printf("Enter name: ");
fgets(name, sizeof(name), stdin);
วิธีที่ 2: ใช้ Space ใน Format String (แนะนำสำหรับ scanf)
scanf("%d", &num);
scanf(" %s", name); // Space นำหน้า %s → ข้าม Whitespace ทั้งหมด
วิธีที่ 3: ใช้ fgets() ทั้งหมด + sscanf() (Best Practice)
char line[100];
int num;
char name[50];
fgets(line, sizeof(line), stdin);
sscanf(line, "%d", &num);
fgets(name, sizeof(name), stdin);
name[strcspn(name, "\n")] = '\0'; // ลบ \n
ตัวอย่างโปรแกรมที่แก้ไขแล้ว
#include <stdio.h>
#include <string.h>
struct Student {
int roll;
char name[50];
};
int main() {
struct Student s;
printf("Enter roll number: ");
scanf("%d", &s.roll);
// วิธีแก้: อ่าน \n ทิ้ง
getchar(); // หรือ scanf("%*c");
printf("Enter name: ");
fgets(s.name, sizeof(s.name), stdin);
s.name[strcspn(s.name, "\n")] = '\0'; // ลบ newline
printf("\n--- Student Info ---\n");
printf("Roll: %d\n", s.roll);
printf("Name: %s\n", s.name);
return 0;
}
ผลลัพธ์:
Enter roll number: 3
Enter name: TutorialsPoint
--- Student Info ---
Roll: 3
Name: TutorialsPoint
สรุปวิธีแก้
| วิธี | Code | ข้อดี | ข้อเสีย |
|---|---|---|---|
| getchar() | getchar() หลัง scanf | ง่าย | อ่านทิ้งแค่ 1 Char |
| Space in format | scanf(" %s", str) | สั้น กระชับ | ใช้ได้กับ %s %c %[...] เท่านั้น |
| fgets + sscanf | fgets → sscanf | ปลอดภัยที่สุด ควบคุมได้ดี | โค้ดยาวกว่า |
⚠️ ห้ามใช้ gets()
gets() ถูก Deprecated และลบออกจาก C11** เพราะไม่มี Bounds Checking → Buffer Overflow Vulnerability
ใช้ fgets() แทนเสมอ