scanf 102

ในการเขียนโปรแกรมแนวคอมโอ เมื่อเขียนด้วยภาษา C จะมีโจทย์บางแบบ ที่ถ้าเรา scanf ดีๆ แล้วจะทำให้ชีวิตง่ายขึ้นมาก เพราะถ้าเราเอา C มาจัดการ string ชีวิตจะเศร้าลงทันที

วันนี้ผมนั่งทำโจทย์ Tree summing ใน uva แล้วหาวิธีการ scanf แนวที่ให้มัน check คล้ายๆ regular expression แล้วก็ไม่เจอข้อมูลเป็นชิ้นเป็นอัน (หรือหาไม่ดีเองหว่า?)  เลยพยายามนั่งทำแล้วรวบรวมมาให้ครับ ถือเป็นวิชา scanf 102 ต่อจากวิชา 101 พื้นฐานที่เราใช้รับเลข รับ string กันเป็นอยู่แล้ว

  • scanf(“%[ABC]”,str)
    • คือ scan ไปเรื่อยๆ ตราบที่ยังเจอเฉพาะ A,B,C แล้วเอาใส่ str
  • scanf(“%[^ABC]”,str)
    • คือ scan ไปเรื่อยๆ ตราบที่ “ไม่เจอ” แต่ A,B,C แล้วเอาใส่ str
    • scan ครั้งต่อไปจะเจอ A เป็นตัวแรก
  • การมี * อยู่หน้า [] คือการ scan อะไรที่เข้าเงื่อนไข ทิ้ง
  • ตัวอักษรที่ไม่ได้อยู่ตาม % ก็คือทิ้งเหมือนกัน เจอตัวอะไรก็ ทิ้งตัวนั้น 1 ตัว
  • scanf(“%*[^(]”)
    • คือ ทิ้งทุกตัวจนกว่าจะเจอ วงเล็บเปิด ‘(‘
    • ก่อนหน้านี้ลอง ทิ้งตัวที่อาจจะเจอ เช่น scanf(“%*[\n ]”); แล้วปรากฏว่าไม่ชัวร์เท่าวิธีนี้ครับ
  • scanf(“(%[-0-9]”,str)
    • แปลว่า เอาเครื่องหมาย – และตัวเลข 0-9
    • ความหมายเดียวกับ scanf(“%[-1234567890]”,str);
  • result = scanf(“(%[-1234567890]”,str);  ควรมีตัวแปรเก็บค่า return
    • อาการที่เหมือนว่ามัน scan เอาค่าเดิมเข้าไป (เช่น print ตัวแปรที่รับค่านั้นออกมาซ้ำ) จริงๆ แล้วคือ มัน scan ไม่เข้า
    • อาการนี่ check ได้โดยการ if(result==0) ถ้าเป็น 0 ชัวร์ได้เลยว่า ตัวแปรจะไม่รับค่าใหม่ใดๆ

ตัวอย่าง code นี้จะสามารถอ่าน tree ในแบบในโจทย์ออกมาได้เลย เมื่อเรียก gentree(0) เช่น

input = (5(4(11(7()())(2()()))()) (8(13()())(4()(1()()))))
output = num[0]=5 num[1]=4 num[3]=11 num[7]=7 num[8]=2 num[2]=8 num[5]=13 num[6]=4 num[14]=1

void gentree(int where){
    int num;
    int result;
    scanf("%*[^(]");
    result = scanf("(%d",&num);
    if(result!=0){
        printf("num[%d]=%d ",where,num);
        gentree(where*2+1);
        gentree(where*2+2);
    }
    scanf("%*[^)])");
}

Tree Summing

7 thoughts on “scanf 102

  1. เคยใช้แต่ [^\n] เพื่อเอาทั้งบรรทัด (เอาช่องว่างด้วย)
    ตามนัทเทพ เคยเขียนบล็อกไว้ อิอิ
    http://nattster.siamdev.net/2008/09/line-scanf/

    พึ่งรู้ว่ามันเล่นท่าได้เยอะขนาดนี้ เจ๋ง….

  2. โอ้… ฉบับสมบูรณ์จริงๆ

    เดี๋ยวจะไปแก้บล็อกให้ ลิงค์มา reference อันนี้ 🙂

Leave a comment