ในบทความนี้จะเป็นการแนะนำวิธีการเปิดอ่านและเขียนไฟล์ Text เพื่อใช้เก็บข้อมูล โดยจะเป็นการใช้งานร่วมกับโครงสร้าง Struct เพื่อจัดกลุ่มข้อมูล หากเพื่อนๆ คนไหนยังไม่ได้อ่านเรื่อง Struct สามารถไปอ่านได้ที่ sunny420x.com/articles/36
ในการอ่านไฟล์หลักๆ แล้วจำใช้คำสั่ง fopen ซึ่งมีประกอบด้วยโหมดต่างๆ ดังนี้
การเปิดไฟล์มีหลายรูปแบบ ยกตัวอย่างคร่าวๆได้แก่
"w" คือโหมดสำหรับเขียนข้อมูลลงในไฟล์ หากไม่มีไฟล์ดังกล่าวโปรแกรมจะสร้างไฟล์นั้นขึ้นมา หากมีข้อมูลอยู่แล้วจะถูกเขียนทับ
"a" คือโหมดสำหรับเขียนข้อมูลลงในไฟล์ โดยจะเขียนต่อจากที่มีอยู่เดิม
"r" คือโหมดสำหรับอ่านไฟล์
"wb" คือโหมดสำหรับเขียนไฟล์ประเภท binary (binary file)
"rb" คือโหมดสำหรับอ่านไฟล์ประเภท binary (binary file)
ผมต้องการสร้างโปรแกรมที่สามารถเพิ่มข้อมูลสินค้า และสามารถแสดงรายการสินค้าออกมาได้ โดยข้อมูลที่จะเก็บคือ id (รหัสสินค้า), name (ชื่อสินค้า) และ price (ราคาสินค้า)
เริ่มแรกผมจะสร้าง โครงสร้าง Struct สำหรับเก็บข้อมูลดังกล่าวไว้นอก main() ดังนี้
struct products {
char id[5];
char name[20];
int price[9];
} products[99];
เมื่อเขียนโปรแกรมตามโจทย์จะได้ประมาณนี้ ซึ่งผมจะอธิบาย Functions ต่างๆ อย่างละเอียด เริ่มที่โปรแกรมที่ผมออกแบบมี Functions สามอัน ได้แก่ menu, readfile, writefile
#include <stdio.h>
struct products {
char id[5];
char name[20];
int price[9];
};
struct products products[99];
int menu();
void readfile();
void writefile();
เนื่องจากการประกาศ Function จำเป็นต้องประกาศไว้บน main() เท่านั้น หากต้องการจะประกาศและเขียนไว้ข้างล่าง main() จำเป็นต้อง นำชื่อ Function ไปประกาศไว้บน main() ดังตัวอย่างข้างบนนี้
int main() {
while (1) {
int input = menu();
if(input == 1) {
writefile();
}
if(input == 2) {
readfile();
}
}
return 0;
}
int menu() {
int input;
printf("------------------------\n");
printf("1) Write Data. \n");
printf("2) Read Data. \n");
printf("------------------------\n");
printf("Enter Options: ");
scanf("%d", &input);
return input;
}
ใน Function main() ผมได้ใช้คำสั่ง while(1) เพื่อให้โปรแกรมรับข้อมูล input ซึ่งคือการเลือก menu ไปเรื่อยๆ และใช้เงื่อนไข if เช็คว่า input เท่ากับ 1 หรือ 2 หรือไม่ หากเท่ากับ 1 ให้ทำงาน function ที่ชื่อว่า writefile หากเท่ากับ 2 ให้ทำงาน function ที่ชื่อว่า readfile
ใน function writefile จะเป็นการเขียนข้อมูลลงในไฟล์ โดยก่อนแรกจำเป็นต้องกำหนด file pointer ก่อน ผมจำใช้ชื่อตัวแปรว่า file โดยใช้คำสั่ง FILE *file; จากนั้นจะใช้คำสั่ง fopen โหมด w เปิดไฟล์ที่ชื่อว่า db.txt จากนั้นผมจะเขียนให้โปรแกรมถามจำนวนรอบที่ต้องการใส่ข้อมูลลงไป ทำการ loop รับข้อมูลเข้ามาเก็บไว้ใน struct และใช้คำสั่ง fprintf เป็นคำสั่งที่สามารถใส่ข้อมูลเข้าไปได้ทีละหลายตัว เมื่อเสร็จแล้วจำเป็นต้องใข้คำสั่ง fclose ทุกครั้ง
ในการอ่านไฟล์มีหลายวิธีการไม่มีว่าจะเป็นการใช้คำสั่ง fgetc ทำการ loop ออกมาทีละตัวอักษร
ใน functions readfile ของผมจะเป็นการนำข้อมูลออกมาทีละ 15 ตัวอักษร ผ่านคำสั่ง fgets เป็นคำสั่งที่นำตัวอักษรออกมาทีละชุด เนื่องจากผมทราบว่าข้อมูลที่ใส่ไม่เกิน 15 ตัวอักษรต่อบรรทัด ซึ่งผมจะเก็บข้อมูลไว้ในตัวแปรที่ชื่อว่า read_buffer โดยจะทำต่อเมื่ออยู่ในเงื่อนไข feof (end-of-file) หมายถึง ทำงานไปเรื่อยๆ จนกว่าจะแสดงข้อมูลออกมาจากไฟล์ทั้งหมด
เมื่อมีการ scanf มากกว่า 2 รอบ มักพบว่าโปรแกรมจะข้ามการทำงานบางบรรทัดไป จึงใช้ fflush(stdin); เพื่อ clear buffer จะพบว่าปัญหาหายไป
void writefile() {
FILE *file;
file = fopen("db.txt", "w");
int amount;
printf("How many rows?: ");
scanf("%d", &amount);
for (int i = 0; i < amount; i++)
{
printf("Enter ID: ");
scanf("%s", products[i].id);
fflush(stdin);
printf("Enter Name: ");
scanf("%s", products[i].name);
printf("Enter Price: ");
scanf("%d", products[i].price);
fprintf(file, "%s %s %d\n", products[i].id, products[i].name, *products[i].price);
}
fclose(file);
}
void readfile() {
FILE *file;
file = fopen("db.txt", "r");
printf("------------------------\n");
printf("id name price\n");
printf("------------------------\n");
char read_buffer[99];
fgets(read_buffer, 15, file);
while(!feof(file)) {
printf("%s \n", read_buffer);
fgets(read_buffer, 15, file);
}
fclose(file);
}

