24 มีนาคม 2554

วิธีแก้ไขเมื่อ scanf ไม่ยอมรับค่า ในภาษา C




          ช่วงนี้ผมก็ทำงาน Project ส่งงานวิชา Unix เสร็จเป็นที่เรียบร้อย แล้วก็ได้ไปช่วยเพื่อนๆ หลายๆ คน และได้ไปพบอยู่คนหนึ่ง มีปัญหาที่ว่า scanf ไม่ยอมรับค่าสักที ทำให้ผมต้องมานั่งไล่ Code เกือบทั้งหมด และก็ค้นพบว่ามันเป็นปัญหาของ stream ของ Keyboard Buffer ไม่ยอมเคลียร์ค่า \n

การที่ scanf ไม่ยอมรับค่า เกิดจากอะไร ?? (๊Update 14-14-2011)
      เกิดจากการอ่านค่าของ scanf ในรูปแบบฟอแมทของพวกตัวเลข จะอ่านเฉพาะตัว string ที่เกี่ยวกับตัวเลขเท่านั้น (0 1 2 3 4 5 6 7 8 9 . + - ) อาจจะมีตัวอื่นอีกนะครับ แต่ในส่วนของตัว '\n' นั้นถือว่าไม่ใช่ string เกี่ยวกับตัวเลข จึง scanf ในฟอแมทของพวกตัวเลข จึงไม่รับ '\n' และค้างอยู่ใน KeyBoard Buffer ทำให้ถูกส่งไปยัง scanf ตัวต่อไป



จากตัวอย่าง Code ที่มีปัญหา ดังนี้
#include <stdio.h>
int main()
{
    int num;
    char name;
    printf("Please input your number : ");
    scanf("%d",&num);
    printf("Please input your char : ");
    scanf("%c",&name);
    
    printf("\n\nyour number is %d\n",num);
    printf("your name is %c",name);
    printf("Finish");
    return 0;   
}

เมื่อทดสอบการรันโปรแกรมแล้วจะพบว่าจะข้ามการรับข้อมูลที่ scanf("%c",&name); และเมื่อทำการแสดงข้อมูลจะเห็นได้ว่า ข้อความ finish ได้ขั้นบรรทัดใหม่ ทั้งๆ ไม่มีการขึ้นบรรทัดใหม่ก่อนหน้านั้น

ฉนั้น จะเห็นได้ว่าเหตุที่ไม่ยอมหยุดรับค่าที่ scanf("%c",&name); เพราะมันได้รับค่า \n จากการใส่ข้อมูลตัวอแรกไปแล้ว

แล้วเราควรแก้ไขอย่างไร ??
     เราสามารถแก้ไขได้โดยการใช้ฟังก์ชัน getchar() ไว้หลัง scanf เพื่อให้ \n ไม่ถูกส่งให้ scanf ตัวต่อไป แต่จะส่งให้ getchar เอง

ตัวอย่าง Code ที่ได้ทำการแก้ไขเสร็จแล้ว
#include <stdio.h>
int main()
{
    int num;
    char name;
    printf("Please input your number : ");
    scanf("%d",&num);
    getchar();
    printf("Please input your char : ");
    scanf("%c",&name);
    getchar();
    
    printf("\n\nyour number is %d\n",num);
    printf("your name is %c",name);
    printf("Finish");
    return 0;   
}

คงจะมีประโยชน์ไม่มากก็น้อยนะครับ ^^

Update
Credits : อ.กบ อ.จิระ


1 ความคิดเห็น: