1. บทนำ

ฟังก์ชัน fgets เป็นฟังก์ชันไลบรารีมาตรฐานของภาษา C ที่ใช้สำหรับอ่านสตริงอย่างปลอดภัย โดยถูกนำมาใช้แทนที่ฟังก์ชัน gets แบบเดิมซึ่งมีความเสี่ยงด้านความปลอดภัย บทความนี้จะอธิบายวิธีใช้ fgets ข้อดีและข้อเสีย รวมถึงเทคนิคในการจัดการอินพุตอย่างปลอดภัย

2. วิธีใช้ฟังก์ชัน fgets เบื้องต้น

2.1 โครงสร้างและพารามิเตอร์ของ fgets

โครงสร้างพื้นฐานของ fgets มีดังนี้

char *fgets(char *str, int n, FILE *stream);
  • str : บัฟเฟอร์สำหรับเก็บสตริงที่รับเข้ามา
  • n : จำนวนอักขระสูงสุดที่จะอ่าน (ขนาดของบัฟเฟอร์)
  • stream : อินพุตสตรีม (โดยปกติใช้ stdin)

2.2 ตัวอย่างโค้ดพื้นฐาน

ด้านล่างนี้คือตัวอย่างการใช้ fgets แบบง่าย ๆ

char buffer[50];
fgets(buffer, 50, stdin);
printf("สตริงที่ป้อนเข้ามา: %s", buffer);

โค้ดนี้จะอ่านค่าที่ผู้ใช้ป้อนเข้ามาสูงสุด 49 อักขระ (เมื่อรวมอักขระนัลเป็น 50) แล้วแสดงผลลัพธ์ออกมา

年収訴求

3. ข้อดีและข้อควรระวังของ fgets

3.1 ความปลอดภัยเมื่อเทียบกับ gets

ฟังก์ชัน gets มีความเสี่ยงเรื่อง buffer overflow และไม่แนะนำให้ใช้งาน ในขณะที่ fgets สามารถกำหนดจำนวนอักขระสูงสุดที่จะอ่าน จึงช่วยป้องกัน buffer overflow ได้

3.2 การจัดการอักขระขึ้นบรรทัดใหม่และบัฟเฟอร์

fgets จะอ่านอักขระขึ้นบรรทัดใหม่ (\n) มาด้วย ซึ่งอาจทำให้เกิดการขึ้นบรรทัดโดยไม่ตั้งใจ และหากข้อมูลอินพุตมีความยาวเกินขนาดบัฟเฟอร์ ข้อมูลที่เหลือจะค้างอยู่ใน stream

4. วิธีจัดการอินพุตอย่างปลอดภัย

4.1 วิธีลบอักขระขึ้นบรรทัดใหม่

สตริงที่อ่านด้วย fgets อาจมีอักขระขึ้นบรรทัดใหม่ติดมาด้วย สามารถลบออกได้ด้วยโค้ดต่อไปนี้

char *newline = strchr(buffer, '\n');
if (newline) {
    *newline = '\0';
}

โค้ดนี้จะแทนที่อักขระขึ้นบรรทัดใหม่ด้วยอักขระนัลเพื่อให้สตริงสะอาด

4.2 วิธีเคลียร์บัฟเฟอร์

หากข้อมูลอินพุตมีความยาวเกินขนาดบัฟเฟอร์ ข้อมูลที่เหลือจะค้างอยู่ในสตรีม ควรเพิ่มโค้ดสำหรับเคลียร์อินพุตดังนี้

while ((getchar()) != '\n' && !feof(stdin));

โค้ดนี้จะอ่านและข้ามข้อมูลที่เหลือใน stream จนกว่าจะพบอักขระขึ้นบรรทัดใหม่หรือถึงจุดสิ้นสุดของไฟล์

5. ข้อควรระวังในการใช้ fgets

5.1 ความสำคัญของการจัดการข้อผิดพลาดและกรณียกเว้น

fgets จะคืนค่าตัวชี้ (pointer) เมื่ออ่านข้อมูลสำเร็จ หากล้มเหลวจะคืนค่า NULL จึงควรตรวจสอบข้อผิดพลาดทุกครั้ง

if (fgets(buffer, sizeof(buffer), stdin) == NULL) {
    // จัดการข้อผิดพลาด
}

5.2 แนวปฏิบัติที่ดีที่สุด

ในการใช้ fgets ควรกำหนดขนาดบัฟเฟอร์และตรวจสอบข้อผิดพลาดทุกครั้ง เพื่อลดความเสี่ยงจาก buffer overflow และควรตรวจสอบความถูกต้องของข้อมูลอินพุตเพื่อความปลอดภัย

6. ตัวอย่างโค้ดสำหรับการใช้งานจริงของ fgets

6.1 การตรวจสอบและทำความสะอาดข้อมูลอินพุต

ในการรับอินพุตจากผู้ใช้ ควรตรวจสอบและทำความสะอาดข้อมูล ตัวอย่างโค้ดด้านล่างรับเฉพาะตัวเลขเท่านั้น

char input[10];
if (fgets(input, sizeof(input), stdin) != NULL) {
    // ลบอักขระขึ้นบรรทัดใหม่
    char *newline = strchr(input, '\n');
    if (newline) {
        *newline = '\0';
    }

    // รับเฉพาะตัวเลข
    if (strspn(input, "0123456789") == strlen(input)) {
        printf("ตัวเลขที่ป้อนเข้ามา: %s\n", input);
    } else {
        printf("อินพุตไม่ถูกต้อง กรุณาป้อนเฉพาะตัวเลขเท่านั้น\n");
    }
}

7. สรุป

ฟังก์ชัน fgets เป็นเครื่องมือที่มีประโยชน์สำหรับการอ่านสตริงในภาษา C อย่างปลอดภัย มีความปลอดภัยมากกว่า gets และลดความเสี่ยงจาก buffer overflow อย่างไรก็ตาม การใช้ fgets ยังต้องคำนึงถึงการจัดการอักขระขึ้นบรรทัดใหม่และการเคลียร์บัฟเฟอร์ด้วย ควรนำเทคนิคที่นำเสนอในบทความนี้ไปใช้เพื่อให้การจัดการอินพุตปลอดภัยและมีประสิทธิภาพ