ปัญหาที่พบบ่อยที่สุด
ใช้ scanf() อ่าน Numeric (int, float) แล้วตามด้วย String → **String ถูกข้ามไป**
ตัวอย่างโค้ดที่ผิด
#include <stdio.h>
struct Student {
char name[10];
int roll;
} s;
int main() {
printf("Enter roll number: ");
scanf("%d", &s.roll); // อ่าน int, ค้าง \n ใน Buffer
printf("Enter name: ");
gets(s.name); // ❌ อ่าน \n ทันที → จบการอ่าน
printf("Roll: %d, Name: %s\n", s.roll, s.name);
return 0;
}
ผลลัพธ์ (ผิด):
Enter roll number: 3
Enter name:
Roll: 3, Name:
เหตุผลทางเทคนิค
scanf("%d")อ่านตัวเลข หยุดที่ Non-digit (\n)\nยังคงอยู่ใน **stdin Buffer**gets()อ่านจนเจอ\n→ เจอทันที → คืน String ว่างscanf("%s")ก็จะข้าม Whitespace แต่gets()ไม่ข้าม
วิธีแก้ (3 วิธี)
1. ใช้ getchar() กิน Newline
scanf("%d", &s.roll);
getchar(); // กิน \n
gets(s.name); // หรือ fgets()
2. ใช้ Space ใน scanf Format
scanf("%d", &s.roll);
scanf(" %s", s.name); // Space นำหน้า %s = Skip Whitespace
3. ใช้ fgets() ทั้งคู่ (Best)
char line[20];
fgets(line, sizeof(line), stdin);
sscanf(line, "%d", &s.roll);
fgets(s.name, sizeof(s.name), stdin);
s.name[strcspn(s.name, "\n")] = '\0';
โค้ดที่ถูกต้อง (ใช้วิธีที่ 1)
#include <stdio.h>
#include <string.h>
struct Student {
char name[50];
int roll;
char dummy; // สำหรับกิน newline
} s;
int main() {
printf("Enter roll number: ");
scanf("%d", &s.roll);
scanf("%c", &s.dummy); // กิน \n
printf("Enter name: ");
fgets(s.name, sizeof(s.name), stdin);
s.name[strcspn(s.name, "\n")] = '\0';
printf("\nRoll: %d\nName: %s\n", s.roll, s.name);
return 0;
}
Best Practices สำหรับ Input ใน C
- หลีกเลี่ยง
scanf()สำหรับ String Input - ใช้
fgets()สำหรับอ่านบรรทัดเต็ม - ใช้
sscanf()Parse จาก String ที่อ่านได้ - ลบ
\nท้าย String ด้วยstrcspn() - Check Return Value ของ scanf/fgets เสมอ