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

Common Error ของ scanf() ในภาษา C: อ่าน String หลัง Numeric


ปัญหาที่พบบ่อยที่สุด

ใช้ 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

  1. หลีกเลี่ยง scanf() สำหรับ String Input
  2. ใช้ fgets() สำหรับอ่านบรรทัดเต็ม
  3. ใช้ sscanf() Parse จาก String ที่อ่านได้
  4. ลบ \n ท้าย String ด้วย strcspn()
  5. Check Return Value ของ scanf/fgets เสมอ