C Language 101 – นานาสาระกับการ Input (EP.6)

จากรอบที่แล้วนะครับ ที่เราได้เรียนรู้เรื่องของ ตัวแปร การเก็บค่า Output อะไรกันไปแล้ว วันนี้เราจะมาเรียนอีกเรื่องนึง ที่ผมลืมพูดไปเลย นั่นคือเรื่องของ Input
คำสั่งที่เราใช้ในการ Input ค่าเข้าโปรแกรมเราหลัก ๆ ก็มีหลายคำสั่งนะ แต่ก่อนอื่นเรามาลองอันที่ง่ายที่สุดก่อน นั่นคือ scanf(); Syntax ของมันคือ

scanf("String_Format",Variable_Address_List);

อย่างที่เขียนด้านบนครับ ก่อนอื่นเราก็ต้องมี String Format ก่อน เช่นพวก %d %f อะไรแบบนี้ เวลาใส่เรียง เราก็ต้องเรียงตามรูปแบบ Input ที่เราต้องการ เช่น ถ้าเราต้องการ Input เป็น
1 2 3 เพราะฉะนั้น String Format ของเราก็ควรจะเป็น %d %d %d อะไรแบบนี้ (เหมือนตอน printf เลย ! )
เสร็จก็ใส่ , (comma) แล้วตามด้วย Address ของตัวแปร

ปัญหาเกิด งานงอก เราจะเอา Address ของตัวแปรมากจากไหน ?

ไม่ยากครับ ในภาษา C มันจะมี Operator ตัวนึง เขาเรียกว่า Address Sign ครับ ถ้าเขียนในโค๊ตก็คือ & (Ampersand) นั่นเอง
จากตอนแรก ถ้าเราบอกว่า int a = 10;
แล้วเราบอกว่า printf("%d",a); เราก็จะได้ 10 ออกมาให้มั้ยครับ
แต่ถ้าเราบอกว่า printf("%p",&a); เราก็จะได้เลข Address ออกมาแทนทั้ง ๆ ที่เราเรียก a เหมือนกับบรรทัดข้างบนเลย นั่นเพราะเราใส่ Ampersand ไว้ก่อนหน้าตัวแปรนั่นเอง
Note: เราจะใช้ %p กับตัวแปร Pointer (แสดง Address) ส่วน Pointer เดี๋ยวไว้ EP. หลัง ๆ เลย เพราะมันค่อนข้างเข้าใจยาก

ลองมาดูตัวอย่าง การใช้ scanf(); กัน

ในตัวอย่างนี้ เราจะมีตัวแปร 3 ตัวนั่นคือ a,b และ c เป็น integer ส่วน Input เราจะให้มันรับค่าเข้ามาบรรทัดเดียว เรียงกัน 3 ตัวเป็น a b c เลย แล้วให้มันแสดงค่าของ a,b และ c ออกมาผ่าน printf();

#include <stdio.h>

int main ()
{
   int a,b,c;
   scanf("%d %d %d",&a,&b,&c);
   printf("%d %d %d",a,b,c);
   return 0;
}

จากโปรแกรมด้านบนก็เป็นเหมือนที่อธิบายด้านบนเลย ก่อนอื่น เราก็ประกาศตัวแปร a, b และ c ขึ้นมาก่อน ซึ่งเราบอกว่าให้มันเป็น Integer หรือจำนวนเต็มนั่นเอง
บรรทัดถัดมา เราก็มาใช้คำสั่งของวันนี้กันนั่นคือ scanf อย่างที่บอกไปว่า เราต้องการ Input ทั้ง 3 ตัวแปรเรียงกันอยู่ในบรรทัดเดียวกันเข้ามารวดเดียวเลย เพราะฉะนั้น เราก็ต้องจัด String Format เป็น %d %d %d
ถามต่อว่า ทำไมเราจะต้องวรรคระหว่าง %d ด้วย นั่นเพราะว่า ถ้าเราไม่แบ่งเนี่ย เวลาเรา Input เข้ามามันจะ งง เช่น เราบอกว่า 104567 มันก็จะเข้าแค่ตัวเดียวนั่นคือ 104567 แล้ว b,c ก็จะไม่ได้รับค่าอะไรเลย
หลังจากนั้นเราก็ printf ตามปกติเลย สุดท้ายก็ return 0; เป็นอันจบโปรแกรม
เพิ่มเติม : เราสามารถที่จะใช้ String Format เป็น %s ได้ด้วยนะ เหมือนเรารับค่าเข้ามาเป็น String แต่จริง ๆ แล้ว ภาษา C มันไม่มี String แต่มันเป็น Array of Char แทน เช่น เราต้องการรับชื่อเราเข้าไป

char name[20];
scanf("%s"name);

ก็ปกติเลย ก่อนอื่นเรารสร้าง Array ของ Char ขึ้นมาก่อน ให้ชื่อว่า name แล้วเราก็ scanf(); เข้ามา โดยใช้ String Format เป็น "%s" แต่ ๆ ๆ ทำไมที่ name ถึงไม่มี Ampersand ล่ะ ? เรื่องนี้เก็บไว้เล่าในเรื่อง Pointer ล่ะกัน เพราะมันเกี่ยวข้องกันอยู่ ตอนนี้เอาเป็นว่า ถ้าเราใช้ %s แล้วข้างหลังเป็น Array ของ char ก็ไม่ต้องใส่ Ampersand ไปก่อนล่ะกัน ถ้าอธิบายเดี่ยวจะยาวเวอร์ !

แต่เดี๋ยวก่อน ! ! !

นอกจาก scanf(); แล้ว ตัวภาษา C ยังมีคำสั่งอื่นอีกที่ใช้รับค่าเข้ามานอกจาก scanf(); นั่นคือ getchar(), getch(), getche() มาดูกันทีล่ะตัวกันเลย

  • getchar() - เจ้านี่จะทำงานคล้าย ๆ กับ scanf() เลย แต่ต่างกันแค่มันรับได้แค่ตัวอักษร (char) เท่านั้นและมันยังรับได้ตัวเดียวอีก น่าเศร้าแท้ Syntax ของมันก็คือ getchar(ตัวแปร); ย้ำว่าตัวแปรนะ ไม่ใช้ Address เพราะฉะนั้นไม่ต้องใส่ Ampersand
  • getch() - อันนี้จะต่างจาก getchar() นิดหน่อย เมื่อตอน getchar(); เวลาเรากด แล้วมันก็จะขึ้นบนหน้าจอ เสร็จแล้วเราก็ต้องกด Enter ด้วย แต่ getch(); แปลกกว่าชาวบ้าน กดปุ๊บไปปุ๊บ ไม่ขึ้นอะไรทั้งนัน ไม่ต้องกด Enter แค่กดปุ่มตามที่เราต้องการเอง
  • getche() - มันจะต่างจาก getch(); นิดหน่อยตรงที่ getch() นั้นเวลาเรากดแล้วมันก็ไม่แสดงอะไร แต่โปรแกรมเราไปเลย แต่เจ้า getche() มันจะแสดงบนหน้าจอว่าเรากดอะไรเข้าไป แต่เราก็ยังไม่ต้องกด Enter เหมือนเดิมนะ

แต่ก็ยังไม่จบอยู่ดี แฮะ ๆ ๆ

เพราะเรายังเหลืออีกคำสั่งเพิ่มขึ้นมา นั่นคือ gets(); หรือก็ย่อมาจาก Get String นั่นเอง หน้าที่ของมันก็ตามชื่อเลย Get String เข้ามานั่นเอง มันจะรับค่าเข้ามาตั้งแต่เริ่มบรรทัดจนสุดบรรทัดเลยทีเดียว มาลองใช้กัน

#include <stdio.h>

int main ()
{
   char name [20];
   gets(name);
}

วิธีใช้ก็ง่ายมาก ๆ เลย เราก็แค่เรียกคำสั่ง gets แล้วข้างในก็เป็นชื่อตัวแปรของเราได้เลย เป็นอันจบ

gets() ต่างจาก scanf(); ยังไง ?

#include <stdio.h>
int main ()
{
   char name[20];

   //using scanf();
   scanf("%s",name);
   printf("%s"name);

   //using gets();
   gets(name);
   printf("%s"name);

   return 0;
}

ในโค๊ตด้านบน เราทดลองเปรียบเทียบ การใช้ scanf() และ gets() ทีนี้ ถ้าเรา Input เข้าไปเหมือนกันทั้ง 2 รอบ โดยผมจะ Input เป็น ชื่อ สกุล ผมล่ะกัน (Arnon Puitrakul)
รอบแรกทาง scanf() เสร็จ printf() ออกมาผลก็จะเป็นแค่ Arnon เท่านั้น เพราะ scanf(); พอเจอ ช่องว่างมันก็ถือว่าจบแล้ว ฉะนั้นนามสกุลผมเลยหายไป
แต่พอมา gets ออกมากลายเป็น Arnon Puitrakul เลยเพราะว่า gets มันอ่านทั้งบรรทัดเลย ไม่สนว่าจะมีช่องว่างอะไรมั้ย เอาให้มันจบบรรทัดไปเลย

สรุป ! ! !

และก็จบอีกเรื่องแล้วกับการ Input สรุปนะครับ คำสั่งที่เราใช้ในการ Input มีหลายคำสั่งมาก ๆ เลย แต่เราก็ต้องเลือกให้เข้ากับงานของเราที่จะเขียนด้วย ถ้างานของเราเป็นรับอะไรง่าย ๆ เช่นตัวเลข scanf(); ก็เป็นทางเลือกที่ไม่เลวเลย แต่ถ้า เราต้องการให้ User เลือก Y/N เราก็ควรที่จะต้องใช้ getche() ก็น่าจะโอเคใช่มั้ยครับ ฉะนั้น อย่างที่บอก เวลาเราใช้ก็ต้องเลือกใช้ดี ๆ นะครับ สวัสดีครับ