450 likes | 866 Views
โครงสร้างของกลุ่มข้อมูลในภาษาซีพลัสพลัส ( ไฟล์ ) Structure of data group in C++ (File). บรรยายครั้งที่ ๑๑. 517112 การโปรแกรมเบื้องต้น ๒ ( Introduction to computer programming II ). อาจารย์รัชดาพร คณาวงษ์ สาขาวิทยาการคอมพิวเตอร์ คณะวิทยาศาสตร์
E N D
โครงสร้างของกลุ่มข้อมูลในภาษาซีพลัสพลัส(ไฟล์)Structure of data group in C++(File) บรรยายครั้งที่ ๑๑ 517112 การโปรแกรมเบื้องต้น ๒ ( Introduction to computer programming II ) อาจารย์รัชดาพร คณาวงษ์ สาขาวิทยาการคอมพิวเตอร์ คณะวิทยาศาสตร์ มหาวิทยาลัยศิลปากร วิทยาเขตพระราชวังสนามจันทร์
ความหมายของไฟล์ • ไฟล์ (file) หมายถึงกลุ่มของข้อมูลซึ่งเก็บอยู่ในลักษณะที่คอมพิวเตอร์สามารถนำไปใช้งานได้ ข้อมูลที่อยู่ในไฟล์อาจจะเป็นโปรแกรม ข้อมูลของโปรแกรม หรือข้อความที่เราเขียนขึ้น • ไฟล์อาจจะเก็บอยู่ในหน่วยความจำ อยู่ในสื่อเก็บข้อมูล เช่น ดิสก์ เทป ซีดี(CD)หรือส่งไปที่พรินเตอร์
ชนิดของไฟล์ • ไฟล์แบ่งออกเป็น 2 ชนิดคือ เท็กซ์ไฟล์ (text file) และไบนารีไฟล์ (Binary file) • เท็กซ์ไฟล์ คือไฟล์ที่ประกอบด้วยตัวอักษร เครื่องหมายต่างๆ ที่ใช้ในข้อความ เครื่องหมายขึ้นบรรทัดใหม่ (carriage return) และเครื่องหมายจบไฟล์ (end of file marker) • ไบนารีไฟล์ คือไฟล์ที่ประกอบด้วยข้อมูลประเภทสตรักเจอร์ หรือมีการบีบอัด(compress) ซึ่งทำให้ข้อมูลมีลักษณะแตกต่างจากเท็กซ์ไฟล์
สตรีม • สตรีม(stream) คือข้อมูลที่มีการเคลื่อนที่ต่อเนื่องกัน เนื่องจากข้อมูลมีการเคลื่อนที่ได้หลายลักษณะ สตรีมจึงมีหลายชนิด สตรีมแต่ละชนิดจะมีคลาสสำหรับสตรีมนั้นโดยเฉพาะ ซึ่งมีชื่อเรียกว่า สตรีมคลาส(stream class) • ภายในสตรีมคลาสจะมีดาตาเมมเบอร์และฟังก์ชันเมมเบอร์สำหรับดำเนินการกับสตรีมนั้นโดยเฉพาะ ดังนั้นแต่ละไฟล์ C++ จึงเป็นออบเจ็กต์หนึ่งของสตรีมคลาส
สตรีมคลาส • ความสัมพันของสตรีมคลาส ios istream fstreambase ostream ifstream ofstream istream_withassign ostream_withassign iostream fstream
สตรีมคลาส • สตรีมคลาสมี ios เป็นเบสคลาส ในคลาส ios มีดาตาเมมเบอร์และฟังก์ชันเมมเบอร์พื้นฐานจำนวนหนึ่งสำหรับทำงานเกี่ยวกับ i/o เช่นฟังก์ชัน get() เป็นต้น • istream และ ostream เป็นดีไรฟ์คลาสของ ios โดย istream ทำหน้าที่เกี่ยวกับอินพุตและ ostream ทำหน้าที่เกี่ยวกับเอาต์พุต ตัวอย่างเมมเบอร์ฟังก์ชัน ใน istreamได้แก่ get(), getline(), read() และโอเปอเรเตอร์ >> ในostreamได้แก่ put(), write() และโอเปอเรเตอร์ <<
สำหรับ coutเป็นออบเจ็กต์ของคลาส ostream_withassign • สำหรับ cinเป็นออบเจ็กต์ของคลาส istream_withassign • iostreamเป็นดีไรฟ์คลาสของ 2คลาสคือ istreamและ ostreamดังนั้น iostreamจึงสืบทอดคุณสมบัติมาจากทั้ง 2 • คลาสที่ทำหน้าที่เกี่ยวกับไฟล์ I/Oมี 3คลาสคือ • ifstream รับข้อมูลจากไฟล์เข้ามาในหน่วยความจำ • ofstream นำข้อมูลจากหน่วยความจำออกไปที่ไฟล์ • fstream ทำหน้าที่ทั้งสองอย่าง ทั้ง 3คลาสเก็บอยู่ในไฟล์ FSTREAM.H
การดำเนินการกับไฟล์ • การดำเนินการกับไฟล์ทั้งเท็กซ์ไฟล์และไบนารีไฟล์ประกอบด้วยกิจกรรมหลัก 2 ประการคือการเก็บข้อมูลเข้าไฟล์และการอ่านข้อมูลจากไฟล์ • การเก็บข้อมูลเข้าไฟล์คือการนำข้อมูลจากหน่วยความจำลงเก็บที่ไฟล์ • การอ่านข้อมูลจากไฟล์คือการนำข้อมูลจากไฟล์เข้ามาไว้ในหน่วยความจำ
วิธีดำเนินการกับไฟล์ข้อมูลสตริงวิธีดำเนินการกับไฟล์ข้อมูลสตริง • สตริง (String) เป็นข้อมูลที่ประกอบด้วยตัวอักษรเรียงต่อกันตามลำดับ ซึ่งเป็นชนิดข้อมูลที่ C++ จัดเป็นคลาสๆ หนึ่งเลย • การดำเนินงานกับสตริงและไฟล์สามารถทำ • การเก็บสตริงเข้าไฟล์ในดิสก์ • การอ่านสตริงจากไฟล์ในดิสก์
การเก็บสตริงเข้าไฟล์ในดิสก์การเก็บสตริงเข้าไฟล์ในดิสก์ • ทำได้โดยเริ่มด้วยการกำหนดออบเจ็กต์ให้เป็นสมาชิกของคลาส ofstream และกำหนดชื่อไฟล์ดังนี้ • ต่อด้วยนำข้อมูลลงไฟล์ด้วยเครื่องหมาย << ดังตัวอย่างต่อไปนี้ ofstream ชื่อออบเจ็กต์(ชื่อไฟล์); ofstream WriteTextFile(“TEST1.TXT”); WriteTextFile << “Saving data into Text File\n”; WriteTextFile เป็นออบเจ็กต์ของคลาสofstream ที่ทำการสร้างโดยการอ้างถึงไฟล์ชื่อTEST1.TXT
โปรแกรม 1 //WriteLineTextFile.cpp #include <fstream.h> #include <conio.h> void main(){ ofstream WriteTextFile(“TEST1.TXT”); WriteTextFile << “C++ is an object-oriented version of the\n”; WriteTextFile << “C programming language, developed by \n”; WriteTextFile << “Bjarn Stroustrup in the early 1980s at \n”; WriteTextFile << “Bell Laboratories.\n”; getch(); } เป็นโปรแกรมสำหรับเก็บข้อความ 4บรรทัดลงไฟล์ในดิสก์ ดังนั้นเราจะไม่เห็นผลลัพธ์ปรากฏบนจอ แต่เราจะเห็นไฟล์ TEST1.TXTถูกสร้างขึ้นในดิสก์ เมื่อทำการเปิดไฟล์นี้ด้วย Editorใดๆ ก็จะเห็นข้อความ 4บรรทัด
การอ่านสตริงเข้าไฟล์ในดิสก์การอ่านสตริงเข้าไฟล์ในดิสก์ • ทำได้โดยเริ่มด้วยการกำหนดออบเจ็กต์ให้เป็นสมาชิกของคลาส ifstream และกำหนดชื่อไฟล์ดังนี้ • ต่อด้วยนำข้อมูลลงไฟล์ด้วยฟังก์ชัน getlineของคลาส istreamดังตัวอย่างต่อไปนี้ ifstream ชื่อออบเจ็กต์(ชื่อไฟล์); ifstream ReadTextFile(“TEST1.TXT”); ReadTextFile.getline(ALine, MaxChar); ReadTextFile เป็นออบเจ็กต์ของคลาสifstream ที่ทำการสร้างโดยการอ้างถึงไฟล์ชื่อTEST1.TXT
ฟังก์ชัน getline • getline() เป็นฟังก์ชันที่เป็นสมาชิกของคลาส istreamซึ่งเป็นดีไรฟ์คลาสของ ifstream ฟังก์ชัน getline() มีรูปแบบดังนี้ istream& getline(char*, int, char=‘\n’); getline() จะอ่านอักษรไฟล์ครั้งละ 1อักษรตามลำดับจนถึง ‘\n’ แล้วจึงเก็บอักษรชุดนั้นไว้ในอาร์กิวเมนต์ที่ 1ของฟังก์ชัน จำนวนอักษรสูงสุดที่เก็บได้จะเท่ากับค่าที่กำหนดไว้ในอาร์กิวเมนต์ 2สำหรับอาร์กิวเมนต์ที่ 2สำหรับอาร์กิวเมนต์ที่ 3เป็นเครื่องหมายแสดงการจบบรรทัด
โปรแกรม 2 //ReadLineTextFile.cpp #include <fstream.h> #include <conio.h> void main(){ const MaxChar = 80; char ALine[MaxChar]; ifstream ReadTextFile(“TEST1.TXT”); while(ReadTextFile){ ReadTextFile.getline(ALine,MaxChar); cout << ALine << endl; } getch(); } เป็นการกำหนดให้อ่านข้อความทีละบรรทัดหรือ 80 ตัวอักษรได้สูงสุดจากไฟล์ TEST1.TXTต่อหนึ่งครั้งการอ่าน และ whileเป็นการตรวจสอบเงื่อนไขว่าจบไฟล์หรือไม่ เพราะถ้าจบไฟล์ ReadTextFileจะเท่ากับ 0
ข้อสังเกต • ชื่อไฟล์ใช้ได้ทั้งตัวอักษรพิมพ์เล็กหรือพิมพ์ใหญ่หรือตัวเลขผสมก็ได้ • ชื่อไฟล์จะรวมที่อยู่ของไฟล์ด้วย เช่นถ้าต้องการเก็บไฟล์อยู่ที่ไดร์ A จะต้องกำหนดชื่อไฟล์ดังนี้ “A:TEST1.TXT”หรือถ้าต้องการเก็บไฟล์อยู่ที่ไดร์ C:ไดเรกทอรี่ DOCจะกำหนดชื่อไฟล์ “C:\DOC\TEST1.TXT” • เมื่อจัดเก็บไฟล์และอ่านไฟล์เสร็จแล้วออบเจ็กต์จะปิดไฟล์ให้โดยอัตโนมัติเราจึงไม่จำเป็นต้องเรียกใช้ดิสตรักเตอร์ในโปรแกรม
วิธีดำเนินการกับไฟล์อักษรวิธีดำเนินการกับไฟล์อักษร • การจัดเก็บอักษรเข้าไฟล์ในดิสก์ ทำได้โดยใช้ฟังก์ชัน put() ซึ่งเป็นฟังก์ชันในคลาส ostream ใช้สำหรับเก็บอักษรเข้าไฟล์ครั้งละ 1 อักษร ฟังก์ชัน put() มีรูปแบบดังนี้ ostream& put(char ch); put() จะทำหน้าที่ส่งค่าอักษร ch ไปเซฟไว้ในไฟล์
โปรแกรมเขียนไฟล์ทีละตัวอักษรโปรแกรมเขียนไฟล์ทีละตัวอักษร //WriteCharTextFile1.cpp #include <fstream.h> #include <string.h> void main(){ char String[] = “C++ is an object-oriented version of the C programming language.”; ofstream WriteTextFile(“TEST2.TXT”); for (int No=0;No<strlen(String);No++) WriteTextFile.put(String[No]); getch(); } เมื่อรันโปรแกรมจะไม่แสดงผลที่จอภาพ เมื่อโปรแกรมรันเสร็จแล้ว เราจะเห็นไฟล์ TEST2.TXTถูกสร้างขึ้นในดิสก์ เมื่อทำการเปิดไฟล์นี้ด้วย Editorใดๆ ก็จะเห็นข้อความใน String
โปรแกรมเขียนไฟล์ทีละตัวอักษรโปรแกรมเขียนไฟล์ทีละตัวอักษร //WriteCharTextFile2.cpp #include <fstream.h> #include <string.h> void main(){ char Ch; ofstream WriteTextFile(“TEST2.TXT”); cout << “To test, type anything.” << endl; cout << “To quit, press ESC.” << endl; do { Ch = getche(); WriteTextFile.put(Ch); }While(Ch!=27); }
วิธีดำเนินการกับไฟล์อักษรวิธีดำเนินการกับไฟล์อักษร • การอ่านอักษรจากไฟล์ในดิสก์ ทำได้โดยใช้ฟังก์ชัน get() ซึ่งเป็นฟังก์ชันในคลาส istream ใช้สำหรับอ่านอักษรจากไฟล์ครั้งละ 1 อักษร ฟังก์ชัน get() มีรูปแบบดังนี้ istream& get(char&); put() จะทำหน้าที่นำอักษร 1 อักษรจากไฟล์มาเก็บไว้ในอาร์กิวเมนต์ของ get()
โปรแกรมอ่านไฟล์ทีละอักษรโปรแกรมอ่านไฟล์ทีละอักษร //ReadCharTextFile1.cpp #include <fstream.h> #include <string.h> void main(){ char Ch; ifstream ReadTextFile(“TEST2.TXT”); While(ReadTextFile) { ReadTextFile.get(Ch); cout << Ch << “-”; } getch(); } เมื่อรันโปรแกรมจะทำการอ่านอักษรจากไฟล์มาทีละตัวอักษร แล้วแสดงผลที่จอภาพ
โปรแกรมอ่านไฟล์ทีละอักษรโปรแกรมอ่านไฟล์ทีละอักษร //ReadCharTextFile2.cpp #include <fstream.h> #include <string.h> void main(){ char Ch,FileName[20]; cout << “Enter file name:”; cin >> FileName; ifstream ReadTextFile(FileName); if (!ReadTextFile) cout << “ERROR <file not found>:” << FileName; else { while(ReadTextFile) { ReadTextFile.get(Ch); cout << Ch; } } getch(); }
วิธีดำเนินการกับไบนารีไฟล์วิธีดำเนินการกับไบนารีไฟล์ • การเก็บข้อมูลเข้าไบนารีไฟล์ในดิสก์ ทำได้โดยใช้ฟังก์ชัน write() ซึ่งเป็นฟังก์ชันในคลาส ostream ฟังก์ชัน write มีรูปแบบดังนี้ ostream& write(const char*, int n); write() จะนำอักษรจากพารามิเตอร์ตัวที่ 1 จำนวน n อักษรไปจัดเก็บในไฟล์ ในที่นี้ค่าของ n ได้รวมอักษรนัลล์ไว้ด้วยแล้ว
โปรแกรมเก็บข้อมูลเข้าไบนารีไฟล์ในดิสก์โปรแกรมเก็บข้อมูลเข้าไบนารีไฟล์ในดิสก์ //WriteObjectToFile.cpp #include <fstream.h> #include <string.h> Class Person { protected: char Name[50]; int Age; public: void GetData(){ cout << “Enter Name:”; cin >> Name; cout << “Enter Age :”; cin >> Age; } }; void main(){ Person APerson; APerson.GetData(); ofstream WriteFile(“PERSON.DAT”); WriteFile.write((char*) &APerson, sizeof(APerson)); }
วิธีดำเนินการกับไบนารีไฟล์วิธีดำเนินการกับไบนารีไฟล์ • การอ่านข้อมูลจากไบนารีไฟล์ในดิสก์ ทำได้โดยใช้ฟังก์ชัน read() ซึ่งเป็นฟังก์ชันในคลาส istream ฟังก์ชัน read มีรูปแบบดังนี้ istream& read(char*, int n); read() จะอ่านอักษรจากไฟล์มาเก็บในพารามิเตอร์ตัวที่ 1 โดยมีจำนวนอักษรตามที่กำหนดไว้ในพารามิเตอร์ที่ 2
โปรแกรมอ่านข้อมูลจากไบนารีไฟล์ในดิสก์โปรแกรมอ่านข้อมูลจากไบนารีไฟล์ในดิสก์ //ReadObjectFromFile.cpp #include <fstream.h> #include <string.h> Class Person { protected: char Name[50]; int Age; public: void ShowData(){ cout << “\nName:” << Name; cout << “\nAge :” << Age; } }; void main(){ Person APerson; ifstream ReadFile(“PERSON.DAT”); ReadFile.read((char*) &APerson, sizeof(APerson)); APerson.ShowData(); }
ไฟล์พอยเตอร์ • ถ้าเราต้องการเก็บและอ่านไฟล์ที่มีหลายออบเจ็กต์ก็สามารถทำได้โดยใช้ฟังก์ชัน open() ซึ่งเป็นสมาชิกของคลาส fstreamฟังก์ชัน open() มีรูปแบบดังนี้ void open(const char* name, int mode, int prot=filebuf::openprot); open() จะเปิดไฟล์ชื่อ name ตามโหมด (mode) ที่กำหนด prot เป็นวิธีการติดต่อกับ DOS ตามปกติจะกำหนดให้ติดต่อเพื่อจัดเก็บและอ่านไฟล์
โปรแกรมที่ใช้ไฟล์พอยเตอร์โปรแกรมที่ใช้ไฟล์พอยเตอร์ //WriteReadObjectFile.cpp #include <fstream.h> #include <string.h> Class Person { protected: char Name[50]; int Age; public: void GetData(){ cout << “Enter Name:”; cin >> Name; cout << “Enter Age :”; cin >> Age; } void ShowData(){ cout << “\nName:” << Name; cout << “\nAge :” << Age; } };
โปรแกรมที่ใช้ไฟล์พอยเตอร์(ต่อ)โปรแกรมที่ใช้ไฟล์พอยเตอร์(ต่อ) void main(){ char Ch; Person APerson; fstream File; File.open(“PERSON.DAT”, ios::app|ios::out|ios::in); cout << “Enter person’s data\n”; do { APerson.GetData(); File.write((char*)&APerson,sizeof(APerson)); cout << “Enter another person(y/n)?”; cin >> Ch; }while(Ch==‘y’); File.seekg(0); File.read((char*)&APerson,sizeof(APerson)); while(!File.eof()) { APerson.ShowData(); File.read((char*)&APerson,sizeof(APerson)); } }
คำอธิบาย • มีคลาส Personมีฟังก์ชันเมมเบอร์ คือ GetData() และ ShowData() • กำหนดให้ APersonเป็นออบเจ็กต์ของคลาส Personและ • Fileเป็นออบเจ็กต์ของคลาส fstreamโดยกำหนดชื่อไฟล์และโหมดเพื่อการเก็บข้อมูลและอ่านข้อมูลที่ตอนท้ายของไฟล์ • ios::inคือเพื่อการจัดเก็บข้อมูล • ios::outคือเพื่อการอ่านข้อมูล • ios::appคือทำการจัดเก็บข้อมูลหรืออ่านข้อมูลที่ตอนท้ายของไฟล์ • ในไฟล์ที่มีหลายออบเจ็กต์จะมีค่าอินทีเจอร์สำหรับชี้ตำแหน่งของแต่ละออบเจ็กต์ ค่าเหล่านี้เรียกว่าไฟล์พอยน์เตอร์(file pointer)
ตำแหน่งของข้อมูลในไฟล์ตำแหน่งของข้อมูลในไฟล์ • การเก็บและอ่านไฟล์จากต้นไฟล์ถึงท้ายไฟล์ การดำเนินกับไฟล์จะเริ่มจากตำแหน่งต้นไฟล์และจบที่ตำแหน่งท้ายไฟล์หรือสัญลักษณ์การจบไฟล์ ถ้าจัดเก็บไฟล์ที่เคยมีข้อมูลเดิมอยู่จะถูกลบและเก็บข้อมูลใหม่แทน • การเก็บและอ่านไฟล์ ณ ตำแหน่งที่กำหนด จะมีการกำหนดตำแหน่งที่จะเก็บหรืออ่านข้อมูลในไฟล์ไว้อย่างแน่นอน ตัวอย่างเช่นการเก็บข้อมูลต่อท้ายข้อมูลเดิมที่มีอยู่ในไฟล์ ส่วนการอ่านจะระบุให้อ่านจากต้นไฟล์จนจบไฟล์ ซึ่งเราต้องเปิดไฟล์ด้วยโหมด ios::app
ฟังก์ชันระบุตำแหน่ง • เรามีฟังก์ชันเพื่อใช้ในการเก็บข้อมูลและอ่านข้อมูลโดยระบุตำแหน่งในไฟล์ดังต่อไปนี้ • tellg(), • seekg(), • tellp() • seekp()
ฟังก์ชันหาค่าตำแหน่งไฟล์พอยเตอร์ฟังก์ชันหาค่าตำแหน่งไฟล์พอยเตอร์ ฟังก์ชันสำหรับหาค่าตำแหน่งของไฟล์พอยเตอร์ซึ่งเป็นตำแหน่งอ่านข้อมูล ฟังก์ชันสำหรับหาค่าตำแหน่งของไฟล์พอยเตอร์ซึ่งเป็นตำแหน่งเก็บข้อมูล long tellg(); streampos tellp();
ฟังก์ชันเลื่อนตำแหน่งไฟล์พอยเตอร์ฟังก์ชันเลื่อนตำแหน่งไฟล์พอยเตอร์ ฟังก์ชันเลื่อนไปที่ตำแหน่งของไฟล์พอยเตอร์ซึ่งเป็นตำแหน่งอ่านข้อมูล ฟังก์ชันเลื่อนไปตำแหน่งของไฟล์พอยเตอร์ซึ่งเป็นตำแหน่งเก็บข้อมูล istream& seekg(streampos pos); หมายเหตุ คำสั่ง File.seekg(0)หมายถึงให้เลื่อนไปที่ตำแหน่งต้นไฟล์เพื่ออ่านข้อมูลตำแหน่งของไฟล์เริ่มจาก 0,1,2,3,… Ostream& seekp(streampos);
ฟังก์ชัน seekg() • รูปแบบที่เห็นคือ istream& seekg(streamoff offset, seek_dir dir); จะเลื่อนไป ณ ตำแหน่งซึ่งอยู่ห่างจากตำแหน่งอ้างอิง dir เท่ากับ offset ไบต์ โดย offset มีทิศทางเปรียบเทียบกับ dir ค่า dir มี 3 ค่าคือ beg(begin), cur(current) และ end ตัวอย่าง File.seekg(0,ios::end);
คำสั่ง seekg seekg(10,ios::beg); beg end seekg(-10,ios::end); beg end seekg(10,ios::cur); beg end
void main(){ char Choice, Ch; int No; Person APerson; fstream File; while(Choice!=‘x’){ File.open(“PERSON.DAT”,ios::app|ios::out|ios::in); File.seekg(0,ios::end); int Amount = File.tellg() / sizeof(Person); cout << “\n>>There are ” << Amount << “person in file <<”; cout << “\nPlease select ...\n”; cout << “..a.. To Add data\n”; cout << “..f.. To Find the person\n”; cout << “..l.. To List data\n”; cout << “..x.. To Exit\n”; cout << “Enter your choice : ”; cin >> Choice; switch(Choice){ case ‘a’: do{ cout << “Enter person’s data\n”; APerson.GetData(); File.write((char*) &APerson, sizeof(APerson)); cout << “Enter another person(y/n)?”; cin >> Ch; }while(Ch==‘y’); File.close();break; case ‘f’: cout << “Enter person number:”; cin >> No; File.seekg((No-1)*sizeof(Person)); cout << “Person #”<< No; APerson.ShowData(); File.close();break; case ‘l’: File.seekg(); File.read((char*)&APerson,sizeof(APerson)); while(!File.eof()){ APerson.ShowData(); File.read((char*)&APerson,sizeof(APerson)); } File.close();break; case ‘x’: File.close();break; default: cout << “\nPLEASE ENTER a, f, l, or x”; File.close(); } } } ตัวอย่างโปรแกรม //WriteReadObjectFile2.cpp #include <istream.h> #include <conio.h> class Person{ protected: char Name[50]; int Age; public: void GetData(){ cout << “Enter Name:”; cin >> Name; cout << “Enter Age :”; cin >> Age; } void ShowData(){ cout << “\nName: ” << Name; cout << “\nAge : ” << Age; } };