ListView Programming Story[5]

ListView Programming Story[5]

นี่เป็นบทความสำหรับ Series ListView ในตอนสุดท้าย ก่อนที่ผมจะหยุดพัฒนามันไป เพราะ เริ่มต้นหาที่เก็บรวบรวมบทความเป็นเวบบล็อก และ ผลจากการเปลี่ยนแปลงระบบงานบัญชีในบริษัทเดิม ทำให้ผมแทบจะไม่ได้ยุ่งเกี่ยวกับงานตรงส่วนนี้มากนัก นอกจากช่วงต้นปีที่ผ่านมา(2008) ที่ต้องมาคิดภาษีให้บริษัท(เดิม)
สำหรับบทความตอนนี้จะเป็นอย่างไร เชิญอ่าน

Success of Listview & File I/O

Now  26/07/2550

Listview & File I/O Operations

จากหัวข้อเดิม ListView & File I/O At 1 Dec 2006 เป็นการพบทางออกในการ Load ข้อมูลจากไฟล์ binary ลง ListView ซึ่งนำเสนอกันลืมไว้แล้วนั้น แม้ว่า จะนำข้อมูลจาก binary file ไปใส่เข้าใน ListView และนำข้อมูลจาก ListView เขียนลงเป็นไฟล์ได้แล้ว แต่การงมโข่งเพื่อหาวิธีจัดการ I/O ด้วย Text File ยังเป็นปัญหาอยู่ และงมอยู่นาน จนกระทั่ง เมื่อ 1 อาทิตย์ที่ผ่านมา (17 กค. 2550) จึงพบทางออก ด้วย Code เก่า ที่อยู่ในไฟล์ เวบที่ save ไว้นานแล้ว แต่ไม่ค่อยได้อ่าน มานั่งอ่านอีกทีแล้วลองวาง code ลงไป ปรากฏว่า สามารถทำได้ จำได้ว่า เป็นเวลาประมาณ 3-4 ทุ่มแล้ว ที่ทำปั๊บ ออกปุ๊บ code ที่ว่า มีดังนี้

/////////////////////////////////////////////////////////////////////////////////
/*
Sample strtok usage to extract words out of a char array
by Ziad Kobti
June 16, 2002
*/

#include
#include

int main()
{
char s[] = “Hello there world”;
char *b[3];

b[0] = strtok(s, ” “);
b[1] = strtok(NULL, ” “);
b[2] = strtok(NULL, ” “);

printf(“%s\n%s\n%s\n”, b[0], b[1], b[2]);

return 0;
}
/////////////////////////////////////////////////////////////////////////////////

/* output:
(5)% cc tt.c
(6)% a.out
Hello
there
world
(7)%
*/

********ส่วนที่ทำตัวหนาไว้ คือ ส่วนหัวใจที่ทำให้งานผ่าน ****************

 

แยกอธิบายดังนี้

เริ่มต้น สร้าง string มา 1 อัน จะรับจากไฟล์ หรือ สร้างเองก็ได้ พร้อมตัวแยก ในตัวอย่างเป็น ตัวว่าง (เว้นวรรค)

จากนั้น ทำ string pointer แบบ array มา 3 ช่อง แต่ละช่องสามารถบรรจุข้อความได้ไม่จำกัดความยาว รอเข้าสิง ตัวแปร

จากนั้น เรียกคำสั่ง strtok มาใช้งานดังนี้

b[0] = strtok(s, ” “);

เราเรียกใช้ คำสั่ง แยก string ออกมาเป็นท่อนๆ เพราะฉะนั้น string pointer b จะต้องแยกร่างเพื่อเข้าสิง string ทีละตัว

ตามปกติแล้ว คำอธิบายของ strtok นั้นมีอยู่ชัดเจนใน e-book หลายเล่มทั้งภาษาไทยและอังกฤษ แต่ตอนนั้น ภาพจากตัวอย่างหรือว่า ความเข้าใจในตอนนั้น ไม่ถึง ก็ไม่ทราบ ทำเท่าไหร่ ไม่ get มุขสักที แต่พอลองทำตามตัวอย่างที่แสนเรียบง่ายนี้กลับผ่าน และทำได้อย่างไม่ยากเย็นนัก สรุปว่า เราคิดกันมากจนเกินไป จนเลยจุดที่สามารถทำได้ ??? – – ‘’ ฮ่วย !!!

เรื่องของเรื่อง ก็คือ จากคำอธิบาย strtok นั้น บอกเราว่า

อันดับแรก เราจะแยก string input ออกมาด้วยตัวแยกตามที่ระบุไว้ในคำสั่งนั้น เช่น แยกด้วย comma หรือ ตัวเว้นวรรค หรือ อื่นๆ ที่ปะปนอยู่ใน string input นั้นๆ  โดยแยกเป็นตัวๆ

ทีนี้ พอแยกเป็นตัวออกมา แล้ว จะไม่ให้ปะปนกันกับตัวอื่นทำไง ก็ทำการปิดท้ายตัว string ที่ถูกแยกออกมาด้วย NULL character [‘’] นั่นแหละ แทนตัวแยกของเราเข้าไป ทำไปจนหมดสาย string input

ลักษณะจะคล้ายๆแบบนี้ครับ

สมมติว่า string input ของเราคือ “Hello,My,World” ตัวแยกคือ comma

เราจะแยกคำว่า Hello ออกมาก่อนด้วยคำสั่งคล้ายที่ยกมาด้านบนดังนี้

b[0] = strtok(s, “,”);

string s จะมี คำว่า “Hello,My,World” อยู่ พอแยกให้อยู่ใน b[0] แล้ว เราจะปิดท้ายด้วย NULL แทนตัว comma ผลที่ได้ก็คือ
Hello [‘’] My,World

แล้วทำไงต่อ

Trick ตรงนี้ไงครับ ที่ผมอ่านไม่รู้เรื่อง แถมดูตัวอย่างอันอื่นก็ไม่ get เสียอีก เลยต้องงมโข่งอยู่ปีกว่า (อีกแล้ว)

กล่าวคือ ให้เราเรียกคำสั่งซ้ำอีกครั้งแต่เรียกแบบนี้ครับ

b[1] = strtok(NULL, “,”);

แบบนี้ หมายความว่า ให้หาตัว [‘’] ให้เจอก่อนแล้วให้วิ่งผ่าน string ที่ต่อท้าย NULL จนกว่าจะเจอ ตัวแยกตัวถัดไปครับ จากนั้น ค่อยดึงตัว string นั้นออกมาพร้อมกับปิดด้วย [‘’] แทนตัวแยกอีกที
ผลที่ได้จะเป็นแบบนี้ครับ

Hello [‘’] My[‘’]World

จากนั้น ก็ทำซ้ำขั้นตอนเดิมอีกที ตามนี้ครับ

b[2] = strtok(NULL, “,”);

ก็เหมือนเดิมกับตะกี้ แต่มีพิเศษอยู่นิดนึงตรงที่มันจะไม่เจอ ตัวแยกแล้ว จากรูปที่แสดงไว้ข้างบน แต่มันก็ไปเจอตัว NULL อีกตัวนึงที่ใช้จบ string ก็เป็นอันว่า จบสิ้นการแยกข้อความออกมา ผลที่ได้จะกลายเป็นแบบนี้ครับ

Hello [‘’] My[‘’]World[‘’] <– NULL [‘’] สีแดงตัวนี้ เป็นตัวที่ใช้จบสาย string ในภาษาซีอยู่แล้ว

ก็คือสรุปว่า ฟังก์ชั่นนี้แยก string ครบ 3 ตัวแล้ว

ปัญหาที่พบและทำให้งมโข่งคืออะไร

ปัญหาคือ ความสับสนในการใช้ strtok(s,sep) กับ strtok(NULL,sep) สำหรับตัวแรกนั้นไม่น่าสับสนอะไรนัก พอใช้งานได้ง่าย แต่พอขึ้นหลักที่สอง จะเริ่มมีปัญหาคือไม่รู้ว่า จะใช้ ตัวหลังกี่รอบ ซี่งขึ้นอยู่กับจำนวนของตัวแยกว่า มีกี่ตัว

สำหรับบางตัวอย่างที่ใช้ while loop เช่น MSDN Example นั้น จะพาออกทะเลไปเลย ทั้งนี้ รวมถึง ตัวอย่างอื่นๆที่นอกเหนือจากที่ยกมาให้ดูนี้ด้วย แต่ตัวอย่างที่ยกมาอันนี้ ก็ยังไม่ดีพอ เพียงแต่ว่า มันสามารถแยก string ออกมาจาก input แบบไหนก็ได้ ให้ออกมาด้วย output คือ ทำการแยก string ออกมาเป็นท่อนๆได้เลย

จริงๆแล้ว วิธีวนลูป ให้จบดีๆ ไม่ error น่าจะเป็นตาม code ต่อไปนี้

For(i=1; i<=Numfield -1; i++)

{

b[i]=strtok(NULL,”,”);

}

ที่ให้ I = 1 เพราะว่า โดนแยกไปตัวนึงแล้ว ส่วน Numfield ก็คือจำนวน string ที่ถูกคั่นด้วยตัวแยก

เช่น ถ้ามีตัวแยก 2 ตัว จะแยก string ออกมาจำนวน 3 ตัว Numfield จะเป็น 3 แต่เนื่องจากแยกออกไปก่อนหน้านี้แล้ว 1 ตัว ก็เลยต้องหักออกไป 1 จะเหลืออีก 2 ตัว ให้วนลูปกัน ซึ่งผลที่ได้ก็ควรออกมาเป็น

B[1]=String ตัวที่ 2 ที่ต้องการแยกออกมา

B[2] = String ตัวที่ 3 ที่ต้องการแยกออกมา

ซึ่งจะใช้ในกรณีที่ Field มันเยอะๆ 7-8 อันขึ้นไป แต่ถ้า 2-5 อัน แบ่งออกมาแสดงทีละอัน แบบที่ยกตัวอย่างมาก็น่าจะใช้ได้แล้ว

ทีนี้ พอแยก string ออกมาเป็น field  สำเร็จแล้ว ถ้าจะ Add เข้า ListView  ให้ทำตามขั้นตอนของการ Add ข้อมูลลง ListView ได้เลย

จบแล้ว ^_^

 

ListView Programming Story[5]
Tagged on:                 

Leave a Reply

Your email address will not be published. Required fields are marked *

Close
E-mail It