0Pricing
C Academy · บทเรียน

ข้อผิดพลาด I/O ที่พบบ่อย

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

ข้อผิดพลาด I/O ที่พบบ่อย เป็นบทเรียน C Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C Academy มีบทเรียนทั้งหมด 4 บทเรียน

ข้อผิดพลาดทั่วไปของข้อมูลนำเข้าและส่งออก

ข้อมูลนำเข้าและส่งออกในภาษา C มีจุดพลาดสำคัญอยู่ไม่กี่ประการ หากรู้จักไว้จะช่วยประหยัดเวลาการแก้จุดบกพร่องได้หลายชั่วโมง

#include <stdio.h>
int main(void) {
    printf("Let us study I/O pitfalls\n");
    return 0;
}

บรรทัดขึ้นบรรทัดใหม่ที่ตกค้าง

หลังจาก scanf("%d", ...) ปุ่ม Enter จะทิ้ง \n ไว้ในบัฟเฟอร์ ต่อมา %c จึงอ่านบรรทัดขึ้นบรรทัดใหม่นั้นแทนข้อมูลจริง

#include <stdio.h>
int main(void) {
    char c = 'A';
    printf("Use a space before %%c to skip the leftover newline\n");
    printf("c = %c\n", c);
    return 0;
}

แก้ไขด้วยการใส่ช่องว่าง

การเขียน scanf(" %c", &c) โดยมีช่องว่างนำหน้า จะบอกให้ scanf ข้ามช่องว่างก่อน

#include <stdio.h>
int main(void) {
    char c = 'Z';
    printf("scanf(\" %%c\", &c) skips whitespace\n");
    printf("c = %c\n", c);
    return 0;
}

ลืมเครื่องหมายแอมเพอร์แซนด์

การส่งตัวแปรให้ scanf โดยไม่มี & จะทำให้จัดเก็บข้อมูลลงในที่อยู่ผิด และอาจทำให้โปรแกรมหยุดทำงาน

#include <stdio.h>
int main(void) {
    int n = 9;
    printf("Always pass &n, not n, to scanf for an int\n");
    printf("n = %d\n", n);
    return 0;
}

ตัวระบุรูปแบบไม่ตรงกัน

การอ่านค่า double ด้วย %f แทน %lf ใน scanf จะทำให้ค่าผิดเพี้ยน การส่งออกใช้ %f ได้ทั้งคู่ แต่ข้อมูลนำเข้าใช้ต่างกัน

#include <stdio.h>
int main(void) {
    double d = 2.5;
    printf("scanf needs %%lf for double; printf uses %%f\n");
    printf("d = %.1f\n", d);
    return 0;
}

การบัฟเฟอร์ข้อมูลส่งออก

ข้อมูลส่งออกอาจถูกเก็บไว้ในบัฟเฟอร์และยังไม่ปรากฏทันที การลงท้ายด้วย \n หรือเรียก fflush(stdout) จะล้างบัฟเฟอร์

#include <stdio.h>
int main(void) {
    printf("Flushed by newline\n");
    fflush(stdout);
    return 0;
}

gets เป็นอันตราย

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

#include <stdio.h>
int main(void) {
    char buf[10];
    /* fgets(buf, sizeof buf, stdin); */
    buf[0] = 'H'; buf[1] = 'i'; buf[2] = 0;
    printf("buf = %s\n", buf);
    return 0;
}

บัฟเฟอร์ล้นเมื่อใช้ %s

การใช้ %s ธรรมดาใน scanf อาจเขียนข้อมูลเกินอาร์เรย์ขนาดเล็กได้ โปรดจำกัดความกว้างด้วยค่าอย่าง %19s

#include <stdio.h>
int main(void) {
    char name[20];
    printf("Use %%19s to leave room for the null terminator\n");
    name[0] = 0;
    printf("name length cap protects buffer\n");
    return 0;
}

fgets เก็บบรรทัดขึ้นบรรทัดใหม่ไว้

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

#include <stdio.h>
#include <string.h>
int main(void) {
    char line[] = "hello\n";
    line[strcspn(line, "\n")] = 0;
    printf("[%s]\n", line);
    return 0;
}

การไม่สนใจค่าที่ส่งกลับ

การไม่ตรวจสอบค่าที่ส่งกลับของ scanf หมายความว่าข้อมูลนำเข้าที่ไม่ถูกต้องจะผ่านไปโดยไม่มีการแจ้งเตือน โปรดตรวจสอบทุกครั้ง

#include <stdio.h>
int main(void) {
    int n = 3;
    int items = 1;
    if (items != 1)
        printf("bad input\n");
    else
        printf("ok: %d\n", n);
    return 0;
}

การนำทุกอย่างมาประกอบกันอย่างปลอดภัย

รูปแบบที่รัดกุมคือ อ่านด้วย fgets แยกวิเคราะห์ด้วย sscanf แล้วตรวจสอบผลลัพธ์

#include <stdio.h>
int main(void) {
    char line[] = "123";
    int n;
    if (sscanf(line, "%d", &n) == 1)
        printf("parsed %d\n", n);
    return 0;
}

ตรวจสอบอย่างรวดเร็ว

ทดสอบความเข้าใจเกี่ยวกับจุดพลาดของข้อมูลนำเข้าและส่งออก

สรุป: จุดพลาดทั่วไปของข้อมูลนำเข้าและส่งออก

คุณได้เรียนรู้วิธีหลีกเลี่ยงข้อผิดพลาดทั่วไปแล้ว

  • บรรทัดขึ้นบรรทัดใหม่ที่ตกค้างทำให้ %c สับสน ให้ใช้ช่องว่างนำหน้า
  • ส่งที่อยู่ด้วย & ทุกครั้ง
  • ใช้ %lf สำหรับอ่านค่า double
  • เลือกใช้ fgets แทน gets และจำกัดความกว้างของ %s
  • ตรวจสอบค่าที่ส่งกลับและล้างบัฟเฟอร์ข้อมูลส่งออก

คำถามที่พบบ่อย

บทเรียน “ข้อผิดพลาด I/O ที่พบบ่อย” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “ข้อผิดพลาด I/O ที่พบบ่อย” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “ข้อผิดพลาด I/O ที่พบบ่อย”

ปัญหาบัฟเฟอร์และการขึ้นบรรทัดใหม่ คุณปฏิบัติ C Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน C Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน

บทเรียน “ข้อผิดพลาด I/O ที่พบบ่อย” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน C Academy นี้ได้ไหม

ได้ บทเรียน C Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. ตัวระบุรูปแบบของ printf
  2. scanf และข้อมูลเข้า
  3. ความกว้าง ความแม่นยำ และแฟล็ก
  4. ข้อผิดพลาด I/O ที่พบบ่อย
← กลับไปที่ C Academy