วันเสาร์ที่ 29 สิงหาคม พ.ศ. 2552

การจัดการกับไฟล์

ชนิดของไฟล์


        ไฟล์ (files)หรือแฟ้ม ที่จะศึกษากันนี้แบ่งเป็น 2 ชนิด คือ


     1. แฟ้มข้อความ หรือ text files  ไฟล์ประเภทนี้จะจัดเก็บข้อมูลเป็นข้อความในรูปของรหัสแอสกี (ASCII) ไฟล์ประเภทนี้ ส่วนมามีส่วนขยาย เป็น txt , bat  c ini nfg log bak  หรืออื่น ๆ ไฟล์เหล่านี้สามารถเปิดได้โดยใช้ text editor  เช่น  notepad โดยจะปรากฏเป็นข้อความ ไฟล์เหล่านนี้เมื่อใช้รหัสบางอย่าง เช่น \n เวลาบันทึกไฟล์ จะถูกเปลี่ยนเป็น  รหัส carriage return หรือ line feed และเมื่ออ่านไฟล์เหล่านี้รหัสนี้จะถูกเปลี่ยนเป็น \n  


      2. แฟ้มในระบบเลขฐานสอง หรือ binary files ไฟล์เหล่านี้จัดเก็บข้อมูลไว้ในรูปเลขฐานสอง เมื่อบันทึกไฟล์ประเภทนี้ จะไม่เปลี่ยนรหัสคำสั่ง เช่น \n เป็น carriage return หรือ line feed  ไฟล์ประเภทนี้ไม่สามารถเปิดด้วย notepad เปิดขึ้นมาจะได้สัญลักษณ์ต่าง ๆ ซึ่งดูไม่รู้เรื่อง ต้องเปิดด้วยโปรแกรมเฉพาะที่จัดการกับแฟ้มเหล่านั้น เช่น ไฟล์ที่มีส่วนขยาย xls doc exe com bmp gif  dat  jpg เป็นต้น


 


ขั้นตอนการจัดการกับไฟล์ หรือขั้นตอนในการเขียนโปรแกรมกับไฟล์


      อาจพิจารณาแบ่งเป็น 3 ขั้นตอน คือ


1. การเปิดไฟล์


2. การประมวลผลข้อมูลในไฟล์ เช่น การอ่าน การจัดเก็บ การแก้ไข การเพิ่ม และ การลบข้อมูล


3. การปิดไฟล์


                ในการจัดกระทำกับไฟล์ เช่น การแก้ไข การเพิ่ม ฯลฯ ไม่ได้กระทำกับไฟล์ที่เก็บอยู่ในดิสก์ หรือ ฮาร์ดดิสก์ โดยตรง แต่กระทำกับพื้นที่ในหน่วยความจำ(memory) ซึ่งเป็นเครื่องคอมพิวเตอร์จัดเตรียมไว้เพื่อประมวลผลเกี่ยวกับไฟล์ หน่วยความจำที่จัดเตรียมไว้เพื่อเป็นตัวกลางในการประมวลผลกับไฟล์นี้เรียกว่า บัฟเฟอร์ เข่น ถ้าจะกระทำการกับไฟล์ 3 ไฟล์ คือ ไฟล์ x ,y ,z  คอมพิวเตอร์จะเตรียมบัฟเฟอร์ไว้ 3 ส่วนสำหรับแต่ละไฟล์


                ไฟล์ในภาษาซีมีการจัดเก็บในลักษณะเรียงต่อกันไปตั้งแต่ต้นจนจบไม่มีการแบ่งเป็นช่วง ดังนั้นการจะกระทำกับข้อมูลในไฟล์จะต้องระบุตำแหน่ง สิ่งที่ใช้ในการหาตำแหน่งของข้อมูลในไฟล์  โดยใช้ตัวชี้ตำแหน่งไฟล์ เรียกว่า ไฟล์พอยน์เตอร์ (file pointer) โดยเมื่อเปิดไฟล์จะต้องมีการสร้างตัวชี้ไฟล์หรือไฟล์พอยน์เตอร์ ซึ่งจะชี้ไปยังตำแหน่งเริ่มต้นของไฟล์ และเปลี่ยนตำแหน่งไปยังตำแหน่งที่ถูกระบุ ในการประมวลผลหลายไฟล์ แต่ละไฟล์จะมีตัวชี้ตำแหน่งเป็นของมันเองไม่ได้ใช้ร่วมกับไฟล์อื่น


 


การเปิดไฟล์


                การเปิดไฟล์จะต้องใช้คำสั่ง 2 คำสั่ง คำสั่งแรกเป็นคำสั่งสร้างพอยน์เตอร์ สำหรับไฟล์ เรียกว่า file pointer สำหรับเก็บค่าตำแหน่งของตัวชี้ไฟล์ และคำสั่งหรือฟังก์ชันในการเปิดไฟล์ คำสั่งสร้างพอยน์เตอร์ เป็น ดังนี้                                FILE  *pointer_name;


โดย   FILE เป็นคำสั่งสำหรับสร้างพอยน์เตอร์ ใช้ตัวพิมพ์ใหญ่ ทั้งคำ


          *  เป็นเครื่องหมายแสดงว่าเป็น พอยน์เตอร์


 


                pointer_name เป็นชื่อของตัวแปรที่ใช้เก็บค่าของพอยน์เตอร์


                จากนั้นเปิดไฟล์ โดยใช้ฟังก์ชัน fopen() ซี่งอยู่ในไฟล์เฮดเดอร์ คือ stdio.h จึงต้องใช้คำสั่ง #include <stdio.h> ไว้ด้วย การเปิดไฟล์จะนำค่าตำแหน่งของตัวชี้ไฟล์เก็บไว้ในตัวแปร ที่เกิดจากคำสั่งสร้างพอยน์เตอร์ ดังนี้               pointer_name = fopen("file_name","file_mode");


โดย pointer_name    คือ ชื่อตัวแปรที่สร้างขึ้นในคำสั่งสร้างไฟล์พอยน์เตอร์(คำสั่ง FILE)


        fopen  เป็นฟังก์ชันที่ใช้เปิดไฟล์    file_name ชื่อของไฟล์ที่จะเปิด โดยต้องอยู่ในเครื่องหมายคำพูด และต้องบอกเส้นทาง (ถ้าจำเป็น เมื่อไฟล์ที่สร้างไม่ได้อยู่ในโฟลเดอร์เดียวกับโปรแกรม)


        "file_mode" คือรูปแบบลักษณะของไฟล์ที่เปิด โดยต้องอยู่ในเครื่องหมายคำพูดเช่นเดียวกัน  file_mode นี้จะต้องสอดคล้องกับเป้าหมายในการเปิดไฟล์ โดย file_mode มี ดังตาราง


 












































mode

 


ความหมาย

text file

binary file

"r","rt"

"rb"

เปิดไฟล์เก่าที่มีอยู่แล้วเพื่ออ่านข้อมูลจากไฟล์อย่างเดียว


สิ่งต้องระวัง  ถ้าไม่มีไฟล์นั้น จะเปิดไฟล์ไม่ได้

"w","wt"

"wb"

เปิดไฟล์ใหม่เพื่อบันทึกข้อมูลไว้ในไฟล์อย่างเดียว


สิ่งต้องระวัง  ถ้ามีไฟล์นั้นเป็นไฟล์ที่มีอยู่แล้วข้อมูลเดิมในไฟล์จะถูกลบทิ้ง และสร้างไฟล์ใหม่ในชื่อเดิม

"a","at"

"ab"

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

"r+t"

"r+b"

เปิดไฟล์ที่มีอยู่แล้ว เพื่ออ่านและบันทึกข้อมูลไปเก็บในไฟล์


สิ่งต้องระวัง   ถ้าใช้ mode นี้เพื่อบันทึกข้อมูลร่วมกับฟังก์ชันบันทึกข้อมูลลงไฟล์ จะทำให้บันทึกข้อมูลใหม่ทับข้อมูลเก่าตั้งแต่ต้นไฟล์จนถึงท้ายไฟล์ทำให้ข้อมูลเก่าถูกแทนที่ด้วยข้อมูลใหม่

"w+t"

"w+b"

เปิดไฟล์ใหม่เพื่อบันทึกข้อมูล เพื่ออ่านและบันทึกข้อมูลลงไปในไฟล์


สิ่งต้องระวัง  ถ้าไฟล์ที่ระบุเป็นไฟล์ที่กำลังถูกใช้งานอยู่ จะเป็นการทำลายข้อมูลเดิมในไฟล์ทั้งหมดและสร้างไฟล์ใหม่แทนที่

"a+t"

"a+b"

เปิดไฟล์ที่มีอยู่แล้วเพื่ออ่านข้อมูลจากไฟล์ และเพิ่มข้อมูลเข้าไปท้ายไฟล์


สิ่งต้องระวัง ถ้าไฟล์ข้อมูลที่ระบุให้เปิดเป็นไฟล์ใหม่จะเป็นการสร้างไฟล์ใหม่ตามชื่อที่ระบุ และบันทึกข้อมูลใหม่



 


 


ในการกำหนดค่า mode ถ้าเป็น text file อาจละค่า t ได้ แต่ถ้าเป็น binary file จะต้องใส่อักษร b เสมอ ในการเปิดไฟล์ ถ้าเปิดได้ โปรแกรมจะส่งค่าของ ตัวชี้ตำแหน่งไฟล์ (file pointer) มาให้ แต่ถ้าเปิด ไม่ได้ จะส่งค่า NULL มาให้ ดังนั้นในการเขียนโปรแกรมควรเขียนให้มีการตรวจสอบว่าเปิดไฟล์ได้หรือไม่ เพื่อถ้าเปิดไฟล์ไม่ได้จะได้รู้ ดังตัวอย่าง  ในโปรแกรม ex10_1.c


 


ตัวอย่าง จงศึกษาโปรแกรม ex10_1.c คาดคะเนการทำงานของโปรแกรม และทดสอบว่าเป็นตามที่คาดหรือไม่


/* ex10_1.c  */


#include <stdio.h>


#include <conio.h>


#include <stdlib.h>         /* เพื่อให้ใช้ exit(0); ได้  */


main()


{


clrscr();


char word;


FILE *fp;


fp = fopen("c:\\bcc55\\c_train\\usetoexample.txt","r");   /* ต้องใช้ \\ บอก path เพราะ \ อันเดียวใช้เป็นรหัสควบคุม จึงต้องใช้ \ 2 อันแรกเป็นรหัสควบคุมเพื่อให้แสดงอันที่2 */


if (fp == NULL)  /* ตรวจสอบว่า ค่าของ fp มีค่าเป็น NULL หรือไม่ ถ้า fp == NULL เป็นจริงแสดงว่าเปิดไฟล์ไม่ได้  */


{


    printf("Cannot open file\n");


   exit(0);


}


word = getc(fp);        /* อ่านข้อมูลจากไฟล์ จากไฟล์พอยน์เตอร์ที่ละตัวอักษร เก็บไว้ในตัวแปร ชื่อ word  */


while (word != EOF)  /* กำหนดให้ตรวจสอบว่าพบรหัสสิ้นสุดไฟล์หรือยัง เก็บไว้ในตัวแปร ถ้าเป็นเท็จให้ทำงานต่อ  */


      {


          printf("%c",word);


          word = getc(fp);       /* อ่านข้อมูลจากไฟล์ จากไฟล์พอยน์เตอร์ที่ละตัวอักษร  */


      }


}


 


                การเปิดไฟล์ อาจเกิดการผิดพลาดได้ จากสาเหตุหลายประการ เช่น ไฟล์ที่ต้องการเปิดไม่มีจริง ระบุเส้นทางที่เก็บไฟล์ไม่ถูกต้อง โดยเฉพาะในกรณีที่ไฟล์นั้นไม่ได้อยู่ในเส้นทางที่ระบุ กรณีเส้นทางที่เก็บไฟล์นี้


ปกติเส้นทาง จะใช้เครื่องหมาย เช่น C:\BCC55\STARTBCC.BAT หมายความว่า ไฟล์ชื่อ STARTBCC.BAT  อยู่ในโฟลเดอร์ ชื่อ BCC55 ที่อยู่ในไดรว์ C ในต่ในภาษาซีเครื่องหมาย \  ใช้เป็นรหัสควบคุม ดังนั้นจึงอาจใช้เครื่องหมาย \ ซ้อนกัน 2 อันแทน ในคำสั่งกำหนดเส้นทางการเปิดไฟล์ จึงอาจเขียนเป็น  C:\\BCC55\\STARTBCC.BAT  หรือ ใช้ / แทน โดยเขียนเป็น C:/BCC55/STARTBCC.BAT  นอกจากนี้การเปิดไฟล์อาจเกิดปัญหาจากการที่ ไฟล์นั้นถูกป้องกันไว้ด้วยคำสั่งบางอย่าง เช่นป้องกันไม่ให้อ่าน


 


การปิดไฟล์


                เมื่อเปิดไฟล์ขึ้นมาแล้วและจัดการดำเนินการต่าง ๆ แล้วและไม่ต้องการใช้ไฟล์นั้นแล้วควรจะปิดไฟล์เพื่อจะได้คืนค่าต่าง ๆ ที่เกี่ยวข้องกับไฟล์นั้น คำสั่ง ในการปิดไฟล์ คือ ฟังก์ชัน fclose() ซึ่งใช้ในลักษณะ ดังนี้


fclose(filepointer);


โดยถ้าปิดไฟล์ถ้าปิดสำเร็จ จะคือค่า เป็น 0 มาให้ ถ้าไม่สำเร็จจะส่งค่าอื่น ดังนั้นในการตรวจสอบว่าปิดไฟล์สำเร็จหรือไม่ จำเป็นต้องใช้ not หรือ (!) ช่วย มาให้ สำหรับ filepointer คือ ไฟล์พอยน์เตอร์ที่ใช้ในการเปิดไฟล์  ตัวอย่างการตรวจสอบการปิดไฟล์สำเร็จหรือไม่ ดังตัวอย่าง


 


ตัวอย่างให้ศึกษาโปรแกรม /* ex10_2.c  */  และทดสอบการทำงาน


/* ex10_2.c  */


#include <stdio.h>


#include <conio.h>


#include <stdlib.h>         /* เพื่อให้ใช้ exit(0); ได้  */


main()


{


clrscr();


FILE *fp;


fp = fopen("c:\\bcc55\\c_train\\usetoexample.txt","r");  


if (fp == NULL) 


{    printf("Cannot open file\n");    exit(0);  }


printf("\Can open file.\n");


if (!fclose(fp) )  /* ตรวจสอบการปิดไฟล์ ว่าสำเร็จหรือไม่ ถ้าสำเร็จ จะให้ค่าเป็น 0 ดังนั้นจึงต้องใส่ ! เพื่อให้ถ้าปิดไฟล์ได้จะส่งค่าคืนมาเป็น 0 เมื่อ พบ ! จะได้ค่าเป็นจริง */


{


          printf("Can close file.");  }  }


 


 


                การเก็บข้อมูลลงไว้ในไฟล์


การเก็บข้อมูลไว้ในไฟล์ ขั้นตอนแรกต้องเปิดไฟล์ในโหมดที่สามารถเก็บข้อมูลได้ คือ w w+ a a+ และ r+ จากนั้นจึงใช้ฟังก์ชันที่ใช้ในการเก็บข้อมูลไว้ในไฟล์ ข้อมูลจะถูกเก็บไว้ในบัฟเฟอร์ก่อน ระหว่างนั้นตัวชี้ตำแหน่งไฟล์จะเลื่อนตำแหน่งไป ตามปริมาณข้อมูล เมื่อบัฟเฟอร์เต็มหรือทำการปิดไฟล์ข้อมูลจึงจะถูกจัดเก็บลงไฟล์ ฟังก์ชันที่ใช้จัดเก็บข้อมูลมีหลายฟังก์ชัน


ฟังก์ชัน putc()        มีรูปแบบ คือ   putc(character,filepointer)


โดย  character เป็นค่าคงที่หรือตัวแปรประเภท char ที่ประกอบด้วยข้อมูลตัวอักขระ 1 ตัว ดังนั้น ฟังก์ชันนี้จึงเขียนได้เพียงครั้งละ 1 ตัวอักษร ดังตัวอย่าง


   /*ex10_3.c */


#include <stdio.h>


#include <conio.h>


#include <stdlib.h>


main()


{


    FILE *fpt;


    char a;


    if((fpt =fopen("c:\\bcc55\\c_train\\putcee.dat","w")) == NULL)


    { printf("Error  to open file.");


        printf("\007");


        exit(1);


    }


    printf("Please press <enter> key to quit program.\n");


    printf("Enter your sentence.");


    do


    {


        a = getche();


        putc(a,fpt);


    } while (a != '\r');


    fclose(fpt);


}


 


 


ฟังก์ชัน fputc()        มีรูปแบบ คือ   fputc(character,filepointer)


เป็นฟังก์ชันสำหรับป้อนตัวอักขระลงไปเก็บในไฟล์ที่ละตัว เช่นเดียวกับ putc() โดยสามารถใช้แทนกันได้  


 


ตัวอย่าง  ศึกษาโปรแกรม ex10_4.c คาดคะเนการทำงานและทดสอบว่าเป็นไปตามที่คาดคะเนหรือไม่


/*ex10_4.c */


#include <stdio.h>


#include <conio.h>


#include <stdlib.h>


main()


{


    FILE *fpt;   char letter;   fpt =fopen("c:\\bcc55\\c_train\\fputcee.txt","w");


    if (fpt == NULL)


    {       printf("Cannot open file for you.\n");    exit(0);    }


    for (letter = 'A'; letter <= 'Z';letter++)


    {


    fputc(letter,fpt);          /* บันทึกตัวอักขระลงไฟล์ครั้งละ 1 ตัว */


   }


   fpt = freopen ("c:\\bcc55\\c_train\\fputcee.txt","r",fpt);  /* เปิดไฟล์อีกครั้งเพื่อเปลี่ยนโหมด */


   clrscr();    while (!feof(fpt))    /* ตรวจสอบว่ายังไม่จบไฟล์ */


   {   letter =getc(fpt);                /* อ่านตัวอักขระครั้งละ 1 ตัว จากไฟล์ */


       printf("%c",letter);


   }


   fclose(fpt);       }


 


ฟังก์ชัน freopen() ใช้ในการเปลี่ยนโหมดของไฟล์ หลังจากเปิดไฟล์ในโหมดอื่น รูปแบบการใช้งาน คือ


filepointer = freopen(“file name”,”mode”,file pointer);


file name คือชื่อไฟล์ที่ต้องการเปลี่ยนโหมด   mode  คือ โหมดใหม่ที่ต้องเปลี่ยนไปใช้  file pointer คือตัวชี้ตำแหน่งไฟล์ที่ต้องการเปลี่ยนโหมด


 


ฟังก์ชัน fputs()        มีรูปแบบ คือ   fputs(string,filepointer)


เป็นฟังก์ชันสำหรับป้อนข้อความเข้าเก็บในไฟล์ โดย string คือข้อความอาจเป็นค่าคงที่หรือตัวแปร ดังตัวอย่าง


 


ตัวอย่าง  ศึกษาโปรแกรมตัวอย่างและคาดคะเนผลการทำงานและทดสอบว่าตรงกับการคาดคะเนหรือไม่


  /*ex10_5.c */


#include <stdio.h>


#include <conio.h>


#include <stdlib.h>


main()


{    FILE *fp;     int num=0;      char job[25]


    fp = fopen("c:/bcc55/c_train/job.txt","a+");  


    if (fp ==NULL)   {    printf("Can not open file.\n");    exit(0);      }        clrscr();


    while (num <7)   {      printf("\nPlease enter job that you know.");     gets(job);


        fputs(job,fp);


        num++;      }


    fclose(fp);


    fp =fopen("c:\\bcc55\\c_train\\job.txt","r");


    fgets(job,25,fp);   /* อ่านข้อความจากไฟล์  ข้อความที่อ่านได้จะต่อกันไม่มีขึ้นบรรทัดใหม่ เนื่องจากคำสั่ง fputs() */


    fclose(fp);  


    printf("Data from file = %s",job);  


}


 


ฟังก์ชัน fprintf() มีรูปแบบการใช้ คือ    fprintf(filepointer,control string ,variable list);


โดย filepointer คือตัวชี้ตำแหน่งไฟล์  control string รหัสรูปแบบ และรหัสควบคุมใช้งานเช่นเดียวกับกรณี ฟังก์ชัน printf() ต่างกันที่เก็บลงไฟล์ หรือ แสดงผลที่จอภาพ  ส่วน ,variable list คือ รายการของค่าคงที่ ตัวแปร หรือนิพจน์ที่จะเขียนลงไฟล์ โดยถ้าเป็นค่าคงที่ประเภทข้อความจะต้องอยู่ภายในเครื่องหมาย " "  การใช้งานฟังก์ชัน fprintf() ดูจาก ตัวอย่างในหน้าถัดไป   


 


ตัวอย่าง จงศึกษาโปรแกรม /* ex10_6.c  */  แล้วคาดคะเนผลการทำงานและทดสอบว่าเป็นตามที่คาดคะเนหรือไม่


/* ex10_6.c  */


#include <stdio.h>


#include <conio.h>


#include <stdlib.h>


#include <string.h>


main()


{


    char filename[15],fname[9],period[2] =".",extension[4],word[5][25];


    float fnum;  int inum;  clrscr();


    printf("\nEnter filename that you want ( 1 to 8 character).");


    scanf("%s",fname);


    strcpy(filename,fname);    strcat(filename,period);


    printf("\nEnter extensions that you want ( 1 to 3 character).");


    scanf("%s",extension);


    strcat(filename,extension);    /* กำหนดชื่อไฟล์โดยรับการป้อนผ่านแป้นพิมพ์  */


    FILE *fpt;     printf("%s",filename);   fpt = fopen(filename,"w");     int i;


    fnum=5.25; inum =2;


    for (i=0;i<5;i++)      


    { printf("\nenter string that you want");


        scanf("%s",word[i]);


        fprintf(fpt,"round %d value1 = %8.2f  value2 = %d and wordinfile is = %s\n",i+1,fnum,inum*fnum,word[i]);  /*ป้อนข้อมูลเก็บในไฟล์ โดยใช้ fprintf  */


        fnum = fnum + 5.25; inum = inum + 2;


    }


    fclose(fpt);


}


 


 


ฟังก์ชัน fwrite()  มีรูปแบบดังนี้    fwrite(position,size,n,filepointer);


ฟังก์ชันนี้เป็นฟังก์ชันที่ใช้เก็บข้อมูลไปไว้ในไฟล์ และการเก็บแต่ละครั้งสามารถกำหนดขนาดของข้อมูลได้ โดยความหมายของคำต่าง ๆ ดังนี้


position  คือ ตำแหน่งของตัวแปรหรือข้อมูลที่จะนำไปจัดเก็บลงไฟล์  size  คือ ขนาดของข้อมูลในการจัดเก็บแต่ละครั้ง ซึ่งสามารถหาได้จากการใช้ฟังก์ชัน sizeof()  ส่วน n  คือจำนวนครั้งที่จัดเก็บข้อมูลลงไฟล์ และ filepointer คือ ตัวชี้ตำแหน่งไฟล์  การใช้ฟังก์ชัน fwrite() นี้เหมาะสำหรับไฟล์ไบนารี ดัง ตัวอย่าง


 


ตัวอย่าง ศึกษาโปรแกรม /* ex10_7.c */  แล้วคาดคะเนผลการทำงานของโปรแกรม และทดสอบโปรแกรม


/* ex10_7.c */


#include <stdio.h>


#include <stdlib.h>


#include <conio.h>


struct  person {  char name[20];   int year;  char position[20];  char phone[15];  char email[20];  } p[100];


main()


{   clrscr();     int i,num1;     printf("Enter number of person :");


    scanf("%d",&num1);    /* รับข้อมูลเพื่อกำหนดจำนวน ชุดของข้อมูลที่จะรับเข้า */


    for (i=0;i<num1;i++)       /* เริ่มรับข้อมูลจากแป้นพิมพ์  */


    { printf("enter name of person %d ",i+1);   scanf("%s",&p[i].name);


        printf("enter birth year of person %d ",i+1);      scanf("%d",&p[i].year);


        printf("enter position of person %d ",i+1);       scanf("%s",&p[i].position);


        printf("enter phone of person %d ",i+1);         scanf("%s",&p[i].phone);


        printf("enter email of person %d ",i+1);         scanf("%s",&p[i].email);        }   /* จบการรับข้อมูล */


    FILE *fp;


        fp = fopen("c:\\bcc55\\c_train\\fwriten.dat","w+b"  );     /* เปิดไฟล์ เพื่อเตรียมบันทึกข้อมูล */


    if (fp == NULL) { printf("Error no file was opened for write.");  exit(0);  } /* ทดสอบว่าเปิดไฟล์ได้หรือไม่ */


    else {    for(i=0;i<num1;i++) { fwrite(&p[i],sizeof(p[i]),1,fp);}  /* บันทึกข้อมูลด้วยฟังก์ชัน fwrite()  */


     }


        fclose(fp);   /* ปิดไฟล์ */


}   /* จบฟังก์ชัน main() */


 


 


การอ่านข้อมูลจากไฟล์


           เมื่ออ่านข้อมูลจากไฟล์  ข้อมูลจะถูกอ่านตั้งแต่ตำแหน่งที่ตัวชี้ไฟล์(file pointer) ชี้อยู่ ไปจนจบหรืออ่านครบตามจำนวนที่กำหนดให้อ่าน โดยตัวชี้ตำแหน่งจะเลื่อนตำแหน่งไปตามตำแหน่งที่อ่าน ข้อมูลที่อ่านเข้ามาจะถูกเก็บไว้ในบัฟเฟอร์  โปรแกรมที่เราเขียนขึ้นจะอ่านจากบัฟเฟอร์อีกทีไม่ใช่อ่านจากไฟล์โดยตรง  ในการเขียนโปรแกรมเพื่ออ่านข้อมูลจากไฟล์จะเริ่มต้นจากการเปิดไฟล์โหมดอ่านอย่างเดียว(r) หรือเพื่ออ่านและเขียน(r+)  ต่อจากนั้นจึงใช้ฟังก์ชันที่ใช้ในการอ่านซึ่งมีหลายฟังก์ชันให้เหมาะสม


 


ฟังก์ชัน getc()  และฟังก์ชัน fgetc()     ฟังก์ชัน 2 ฟังก์ชัน นี้ใช้เหมือนกัน คืออ่านตัวอักขระ ณ ตำแหน่งที่ตัวชี้ตำแหน่งไฟล์ชี้อยู่ออกมาครั้งละ 1 ตัวอักขระ รูปแบบการใช้งาน เป็นดังนี้


variable = getc(filepointer);  หรือ  variable = fgetc(filepointer);


โดย variable เป็นแบบ char ตัวอย่าง การใช้งานฟังก์ชัน 2 ฟังก์ชัน นี้เป็นดังตัวอย่าง


 


ตัวอย่าง ศึกษาโปรแกรม ex10_8.c ให้ศึกษาทำความเข้าใจการใช้งานฟังก์ชันgetc() และ fgetc()แล้วทดสอบโปรแกรมนี้


  /* ex10_8.c */


#include <stdio.h>


#include <conio.h>


#include <stdlib.h>


char chgetc,chfgetc;


main()


{    FILE *fgc,*ffgc;     fgc = fopen("c:\\bcc55\\c_train\\license.txt","r");   /* เปิดไฟล์  */


    if (fgc == NULL)   {     printf("Error no file was opened.");      exit(0);    }


    clrscr();     chgetc = getc(fgc);


   printf("\nResult of getc()\n");


    while (chgetc != EOF)  {   printf("%c",chgetc);      chgetc = getc(fgc);      }


    fclose(fgc);   /* ปิดไฟล์  */


 


ffgc = fopen("c:\\bcc55\\c_train\\license.txt","r");    /* เปิดไฟล์  */


    if (ffgc == NULL)   {    printf("Error no file was opened.");     exit(0);     }


    chgetc = getc(fgc);


    printf("\n\nResult of fgetc()\n");


    while (chfgetc != EOF)   {   printf("%c",chfgetc);    chfgetc = fgetc(ffgc);    }


    fclose(ffgc);   }


 


ฟังก์ชัน fgets()   เป็นฟังก์ชันอ่านข้อความจากไฟล์ออกมาต่อเนื่องกันเป็นข้อความโดยกำหนดความยาวของข้อความได้ รูปแบบของการเรียกใช้ฟังก์ชันนี้เป็นดังนี้


fgets(variable_name,size ,filepointer)


โดย คือ variable_name ชื่อของตัวที่ใช้จัดเก็บข้อความที่อ่านมาจากไฟล์  ส่วน size คือ ความยาวของข้อความที่ต้องการอ่านจากไฟล์โดยจำนวนไบต์ที่กำหนดจะมากกว่าความยาวของข้อความ 1 ไบต์ เพราะจำนวน 1 ไบต์ที่เกินนั้นใช้สำหรับรหัส  \0 ซึ่งเป็นรหัสบอกการจบข้อความ โดยถ้าพบรหัสขึ้นบรรทัดใหม่( \n ) หรือรหัสจบไฟล์ (EOF)ฟังก์ชันนี้จะหยุดอ่านข้อความแม้ว่ายังไม่ครบความยาวที่กำหนด   ส่วน filepointer คือ ตัวชี้ตำแหน่งไฟล์


 


ตัวอย่าง จงศึกษาโปรแกรม /* ex10_9.c */    แล้วทดสอบโปรแกรมและลองเปลี่ยนความยาวของข้อความที่อ่านจากไฟล์


  /* ex10_9.c */


#include <stdio.h>


#include <conio.h>


#include <stdlib.h>


char chget[50];


main()


{


    FILE *fgs;


    fgs = fopen("c:\\bcc55\\c_train\\license.txt","r");


    if (fgs == NULL)


    {


        printf("Error no file was opened.");  exit(0);


    }


    clrscr();


    fgets(chget,35,fgs);               /* อ่านข้อความยาว 34 ไบต์ มาเก็บไว้ในตัวแปร chget  */


    fclose(fgs);            /* ปิดไฟล์  */


    printf("Text from file = %s",chget);


while (!feof(fgs))   */ ใช้คำสั่ง while และฟังก์ชันตรวจการจบไฟล feof() มาช่วยให้อ่านข้อความได้มากขึ้น */


{    fgets(chget,35,fgs);               


    printf("Text from file when use with while statement = %s",chget); }


    fclose(fgs);            /* ปิดไฟล์  */


 }


 


 


ฟังก์ชัน fscanf()   เป็นฟังก์ชันอ่านข้อมูลจากไฟล์(ไฟล์ข้อความหรือ text file) ลักษณะการใช้งานเหมือนกับฟังก์ชัน scanf() ต่างกันที่อ่านจากไฟล์กับรับค่าจากแป้นพิมพ์  รูปแบบการใช้งานเป็น ดังนี้


fscanf (filepointer,control string,variable list)


โดย filepointer เป็นตัวชี้ตำแหน่งไฟล์    control string เป็นรหัสรูปแบบเหมือนกับในฟังก์ชัน  scanf() คือ สามารถใช้  %d %s \n เป็นต้น  variable list เป็นรายการของตัวแปรที่ใช้เก็บข้อมูลที่อ่านมาจากไฟล์ โดยต้องใช้เครื่องหมาย & นำหน้าชื่อตัวแปร ยกเว้นตัวแปรข้อความ (string) ไม่ต้องใช้เครื่องหมาย & นำหน้าชื่อตัวแปร 


         ลักษณะการใช้งานฟังก์ชันนี้ใช้อ่านข้อมูลประเภท ตัวอักขระ  ข้อความ หรือตัวเลข ขึ้นอยู่กับรูปแบบที่กำหนด และปกติการใช้ฟังก์ชันนี้จะใช้กับไฟล์ที่มีการกำหนดรูปแบบไว้ด้วย เช่น การบันทึกข้อมูลไว้ในไฟล์ด้วยคำสั่ง fprintf() โดยต้องพึงระวังว่าการอ่านไฟล์โดยใช้ฟังก์ชันนี้ต้องนึกไว้ว่าการกำหนดรูปแบบการอ่านต้องให้ตรงกับรูปแบบในไฟล์มิฉะนั้น อาจเกิดการผิดพลาดได้


 


ตัวอย่าง   ให้ศึกษาโปรแกรม วิเคราะห์ และทดสอบโปรแกรม ว่าเป็นตามที่คิดหรือไม่


   /* ex10_10.c  */


#include <stdio.h>


#include <conio.h>


#include <stdlib.h>


main()


{  int num,age;  char name[15],surname[15];    FILE *fp; 


    fp = fopen ("c:\\bcc55\\c_train\\ex10_10.txt","w+t");


    if (fp == NULL)  {    printf("Error cannot open file.");   exit(0);     }


    num=0;


    while (num<5)     {     clrscr();     printf("\nPlease type name :");      scanf("%s",name);


        printf("\nPlease type surname :");      scanf("%s",surname);


        printf("\nPlease type age :");        scanf("%d",&age);


        fprintf(fp,"\n %s %s %d",name,surname,age);      num++;       }


        fp = freopen("c:\\bcc55\\c_train\\ex10_10.txt","r+t",fp);  /* เปิดไฟล์ใหม่เพื่อเปลี่ยนโหมด */


    clrscr();


    while (!feof(fp))    {


     fscanf (fp,"%s%s%d",name,surname,&age);        /* ใช้ฟังก์ชัน fscanf()  เพื่ออ่านข้อมูลจากไฟล์  */


     printf("\n%s %s %d",name,surname,age);     }


    fclose(fp);  


}


 


 


ฟังก์ชัน fread()   เป็นฟังก์ชันอ่านข้อมูลจากไฟล์โดยเฉพาะไฟล์ไบนารี  และไฟล์ที่เก็บข้อมูลที่มีลักษณะโครงสร้าง ที่สร้างโดยใช้คำสั่ง struct  และจัดเก็บไว้ด้วยฟังก์ชัน fwrite() โดยการกำหนดโครงสร้างในการอ่านให้สอดคล้องกับเมื่อบันทึกข้อมูลลงไฟล์  รูปแบบของฟังก์ชัน fread() เป็นแบบเดียวกับ fwrite() ดังนี้


fread(position,size,n,filepointer);


โดยความหมายของคำต่าง ๆ ในฟังก์ชัน ก็เป็นเช่นเดียวกันในทั้งสองฟังก์ชัน


 


ตัวอย่าง ให้ศึกษาโปรแกรม วิเคราะห์ และทดสอบโปรแกรม ต่อไปนี้


/* ex10_11.c */


#include <stdio.h>


#include <stdlib.h>


#include <conio.h>


#include <string.h>


struct  person {  char name[20];   int year;   char position[20];   char phone[15];  char email[20]; } p[100];


main()


{    clrscr();    int i,j,num;


    FILE *fp;     fp = fopen("c:\\bcc55\\c_train\\fwriten.dat","r+b");             /* เปิดไฟล์  */


    if (fp == NULL)


    {     printf("Error no file was opened for read.");   exit(0);     }


    else { i=0;


        while (!feof (fp)) { fread(&p[i],sizeof(p[i]),1,fp); i++;}                  /* อ่านข้อมูลโดยใช้ fread() */


        }


        num = i-1;     /* ตัวแปรที่กำหนดให้สอดคล้องกับจำนวนข้อมูลที่อ่านเข้ามา */


        printf("DATA from file %s \n","fwriten.dat");


           j=0;


while (j < num)                            /* เริ่มต้นนำข้อมูลที่อ่านได้ไปแสดงผลทางจอภาพ  */


    { 


        printf("\n\tperson number %d \tname %s \tbirth year %d",j+1,p[j].name,p[j].year);


        printf("\n\tposition %s \tphone %s \temail %s",p[j].position,p[j].phone,p[j].email );


        j++;


    }


        fclose(fp);             /* ปิดไฟล์ */


}            /* จบฟังก์ชัน main()   */


 


 


ฟังก์ชัน จัดการตำแหน่งพอยน์เตอร์ในไฟล์


        เมื่อเขียนข้อมูลลงไฟล์หรืออ่านข้อมูลจากไฟล์ ตำแหน่งของตัวชี้หรือ file pointer จะเปลี่ยนไป เพื่อให้ตัวชี้กลับไป ยังตำแหน่งเริ่มต้นในไฟล์(BOF = beginning of file) เราต้องปิดไฟล์แล้วเปิดไฟล์ใหม่หรือเปลี่ยนโหมดในการเปิดไฟล์ หรือ ใช้ฟังก์ชันบางฟังก์ชัน ในภาษาซีมีฟังก์ชันที่ใช้เปลี่ยนตำแหน่งของตัวชี้ในไฟล์ หลายฟังก์ชัน


ฟังก์ชัน rewind()


เป็นฟังก์ชันที่ทำให้ตัวชี้ตำแหน่งในไฟล์กลับไปอยู่ ณ ตำแหน่งเริ่มต้นของไฟล์ มีรูปแบบการใช้ คือ rewind(filepointer)


ฟังก์ชัน ftell()  มีรูปแบบการใช้ คือ    ftell(filepointer)


           เป็นฟังก์ชัน ที่ใช้บอกตำแหน่งที่ตัวชี้อยู่ในขณะปัจจุบัน โดยจะแสดงเป็นตัวเลขของไบต์ของข้อมูลที่ตัวชี้ชี้อยู่ โดยจุดเริ่มต้นของไฟล์ของไบต์แรก


 


ตัวอย่าง ให้ศึกษาโปรแกรม วิเคราะห์ และทดสอบ โดยเน้นที่ ฟังก์ชัน การเปลี่ยนตำแหน่งของตัวชี้


/*ex10_12.c */


#include <stdio.h>


#include <conio.h>


#include <stdlib.h>


main()


{     FILE *fpt;   int letter; clrscr();   fpt =fopen("c:\\bcc55\\c_train\\fputcee.txt","w+t");


    if (fpt == NULL)    {   printf("\n Cannot open file for you.\n");    exit(0);    }


    for (letter = 'A'; letter <= 'Z';letter++)


    {    fputc(letter,fpt);          /* บันทึกตัวอักขระลงไฟล์ครั้งละ 1 ตัว */


   }


   int byt;    byt = ftell(fpt);    printf("\n Value of position of filepointer before rewind = %d\n",byt);


   rewind(fpt);  /* ให้filepointer กลับไปอยู่ที่ต้นแฟ้ม */


   byt = ftell(fpt);    printf("\n Value of position of filepointer after rewind = %d\n",byt);


   while (!feof(fpt))    /* ตรวจสอบว่ายังไม่จบไฟล์ */


   {     letter =getc(fpt);                /* อ่านตัวอักขระครั้งละ 1 ตัว จากไฟล์ */


       printf("%c",letter);


   }


   fclose(fpt);


   }   /* จบโปรแกรม  */


 


 


ฟังก์ชัน  fseek() 


เป็นฟังก์ชันที่ใช้เปลี่ยนตำแหน่งที่ filepointer    ชี้อยู่ มีรูปแบบการใช้งานดังนี้


fseek(filepointer,offset,origin)


โดย filepointer คือ ตัวชี้ตำแหน่งที่เราต้องการเปลี่ยนตำแหน่งที่ชี้


 offset  คือ ค่าตำแหน่งที่เพิ่มหรือลดจากตำแหน่งอ้างอิง มีหน่วยเป็นไบต์ ใช้ค่าเป็นบวกเมื่อเลื่อน filepointer  ไปทางท้ายของไฟล์ และมีค่าเป็นลบเมื่อเลื่อน filepointer  ย้อนมาทางต้นไฟล์ และต้องการเลื่อนเกิน 64 ไบต์ให้ใส่ l หลังตัวเลขเพื่อระบุว่าเป็นแบบ long integer


origin คือตำแหน่งอ้างอิงหลักในไฟล์ มี 3 ตำแหน่ง คือตำแหน่งต้นไฟล์(BOF)  ตำแหน่งท้ายไฟล์ (EOF) และตำแหน่งที่ตัวชี้ชี้อยู่ในปัจจุบัน  การระบุตำแหน่งอ้างอิง มี 2 วิธี คือวิธีใช้ค่าคงที่กับวิธีใช้ macro ดังตาราง


 


























ตำแหน่งอ้างอิง(origin)

 ค่า macro ที่ใช้

ค่าคงที่ที่ใช้

filepointer  อยู่ที้ต้นไฟล์ ((BOF)

SEEK_SET

0

filepointer  อยู่ที้ตำแหน่งปัจจุบัน

SEEK_CUR

1

filepointer  อยู่ที้ท้ายไฟล์ ((EOF)

SEEK_END

2



 


ตัวอย่าง เช่น  fseek(fp,10,0)  หรือ  fseek(fp,10,SEEK_SET)  เหมือนกันคือ ให้ filepointer( fp) เลื่อนไปอยู่ตำแหน่งถัดจากต้นไฟล์ไป 10 ไบต์  หรือ คำสั่ง fseek(fp,-65l,2)  หรือ  fseek(fp,-65l,SEEK_END) จะมีความหมายเหมือนกัน คือ ให้เลื่อน filepointer( fp) ไปอยู่ที่ตำแหน่งถัดจากท้ายไฟล์ไปทางต้นไฟล์ 65 ไบต์


ข้อควรจำ ฟังก์ชัน fseek()   จะให้ค่าไม่เท่ากับ 0 เมื่อย้าย filepointer ไม่ได้


 


ตัวอย่าง แสดงการใช้ ฟังก์ชัน fseek() และการหาข้อมูลให้ศึกษาโปรแกรมและทดสอบว่าเป็นตามที่คิดหรือไม่


/* ex10_13.c */


#include <stdio.h>


#include <stdlib.h>


#include <conio.h>


struct person


{   char name[20];      int year;      char position[20];     char phone[15];      char email[20];  } p[100];


main()


{     FILE *fptr;


    int recno;       /* เพื่อกำหนด record ที่ต้องการ */


    long int offset;   /* เพื่อใช้เป็น offset  */


    clrscr();


    if ((fptr = fopen("c:\\bcc55\\c_train\\fwriten.dat","r+b"  ))==NULL)


    { printf("No file was opened.");  exit(0); }


    printf("Enter record number :");        /* เพื่อกำหนดค่า record ที่ต้องการหาข้อมูล */


    scanf("%d",&recno);


    offset = (recno-1)*sizeof(p[recno-1]);   /* เพื่อหาค่า offset หรือจำนวนไบต์ที่ต้องการเลื่อนตัวชี้  */


    if (fseek(fptr,offset,0) != 0)   /* เลื่อนตำแหน่ง ตัวชี้ พร้อมตรวจสอบว่าเลื่อนได้หรือไม่ ไปด้วยในตัว */


    { printf("Can not move file pointer.");  exit(0);  }


   { fread(&p[recno-1],sizeof(p[recno-1]),1,fptr);  /* อ่านข้อมูล จากrecord ที่ต้องการหาข้อมูล*/


     printf("\nName = %s",p[recno-1].name);  /* นำข้อมูลมาแสดงทางจอภาพ */


    printf("\t Birth Year =  %d",p[recno-1].year);      printf("\tPosition = %s",p[recno-1].position);


     printf("\nPhone = %s",p[recno-1].phone);          printf("\temail = %s",p[recno-1].email); }


     fclose(fptr);   /* ปิดไฟล์ */


 }


 


ฟังก์ชัน remove() ใช้ลบไฟล์ รูปแบบ คือ remove(file name)  เช่น


                         result  = remove("c:\\bcc55\\c_train\\t4.txt");  */ result เป็นชื่อตัวแปร */


ข้อควรจำ  ฟังก์ชันนี้ เมื่อลบไฟล์สำเร็จจะให้ค่า 0 หรือ เท็จ กลับมา ถ้าลบไม่สำเร็จ จะให้ค่าอื่นที่ไม่ใช่ 0 ดังนั้นการเขียนโปรแกรม เพื่อตรวจสอบจึงต้องระวัง


ฟังก์ชัน rename() ใช้เปลี่ยนชื่อไฟล์ รูปแบบ คือ rename(old name ,new name) เช่น


      result  = rename("c:\\bcc55\\c_train\\t4.txt","c:\\bcc55\\c_train\\b4.dat");  */ result เป็นชื่อตัวแปร */


ข้อควรจำ  ฟังก์ชันนี้ เมื่อเปลี่ยนชื่อไฟล์สำเร็จจะให้ค่า 0 หรือ เท็จ กลับมา ถ้าเปลี่ยนชื่อไม่สำเร็จ จะให้ค่าอื่นที่ไม่ใช่ 0 ดังนั้นการเขียนโปรแกรม เพื่อตรวจสอบจึงต้องระวัง


ฟังก์ชัน  ferror () ใช้ตรวจสอบว่ามีข้อผิดพลาดจากการอ่านแฟ้มข้อมูลหรือไม่  รูปแบบ คือ ferror(file pointer)


ข้อควรจำ  ฟังก์ชันนี้ ถ้าตรวจสอบว่าไม่มีข้อผิดพลาดจากการอ่านไฟล์จะให้ค่า 0 หรือ เท็จ กลับมา  ถ้าพบข้อผิดพลาด จะให้ค่าอื่นที่ไม่ใช่ 0 ดังนั้นการเขียนโปรแกรม เพื่อตรวจสอบจึงต้องระวัง


ฟังก์ชัน feof()  ใช้ตรวจสอบว่าข้อมูลหมดไฟล์หรือไม่ คือหาว่าจบไฟล์หรือยัง รูปแบบ คือ


             feof(file pointer)


 

ไม่มีความคิดเห็น:

แสดงความคิดเห็น

DEVELOPER ZOne