260 likes | 443 Views
Object Oriented Programming. Tirgul 11: עבודה עם קבצים. זרמי קלט פלט. ב-++ C עבודה עם קלט/פלט מתבסס על זרמים (streams) . ניתן לקרוא / לכתוב נתונים למקלדת/מסך, קבצים, מחרוזות. Program. output stream. input stream. היררכית (חלק) המחלקות. ios, ios_base , iostream :
E N D
Object Oriented Programming Tirgul 11: עבודה עם קבצים
זרמי קלט פלט • ב-++C עבודה עם קלט/פלט מתבסס על זרמים (streams). • ניתן לקרוא / לכתוב נתונים למקלדת/מסך, קבצים, מחרוזות. Program output stream input stream
היררכית (חלק) המחלקות ios, ios_base, iostream: פעולות קלט/פלט בסיסיות. ostream,istream: קלט/פלט תקני. ostringstream ,istringstream: קלט ממחרוזות ופלט למחרוזת ofstream,ifstream: קלט מקובץ ופלט לקובץ
קלט פלט בסיסי – דוגמאות int x,y; cin >> x >> y; while (!cin) { cout << "Error Input\n"; cin.clear(); cin.ignore(); cin >> x >> y; } cout <<“Did it!\n"; A 2 Error Input 2 s Error Input e a Error Input 2 3 Did it!
קלט פלט בסיסי - דוגמאות • <iomanip> - ניתן לבצע מניפולציות על הקלט. לדוגמא: • setw() - קביעת רוחב שדה הפלט. • left, right- הצמדת הנתון בשדה הפלט לשמאל/ימין. • setfill()- קביעת תו המילוי. • setprecision() - קביעת הדיוק בהדפסת מספר ממשי. • fixed - הדפסה בייצוג עשרוני. • scientific- הדפסה בייצוג מעריכי/מדעי. • dec,hex,oct - בסיס המספר.
struct Student { string name; int id; double grade_avg; }; קלט פלט בסיסי - דוגמאות int main() { Student arr[3] = {Student("Hofit", 1111, 98), Student("Eli", 2222, 86), Student("Tali", 3333, 63)}; cout << "name" << " id " << " grade" << endl; cout << "----" << " -----" << " -----" << endl; for(int i=0; i<3; i++) cout << arr[i].name << " "<< arr[i].id << " "<< arr[i].grade_avg << endl; //... }
קלט פלט בסיסי - דוגמאות int main() { Student arr[3] = {Student("Hofit", 1111, 98), Student("Eli", 2222, 86), Student("Tali", 3333, 63)}; cout << left << setw(6) << "name"<< setw(6) << "id"<< setw(6) << "grades" << endl; cout << setfill('-') << setw(>> '-' >> (18setfill(' ') << endl; for(int i=0; i<3; i++) cout << left << setw(6) << arr[i].name << setw(6) << arr[i].id << setw(6) << arr[i].grade_avg << endl; //... }
עבודה עם קבצים • ב-C עבדנו עם מצביע לקובץ, ב-++C ניצור אובייקט שייצג את הקובץ ונפעיל עליו את המתודות שלו. • מחלקות לעבודה עם קבצים: • <ifstream> – קריאה מקובץ. • <ofstream> – כתיבה מקובץ. • <fstream> – קריאה && כתיבה מקובץ.
עבודה עם קבצים • ע"מ לעבוד עם קבצים אנו צריכים את הפעולות הבאות: • פתיחת קובץ. • לקריאה, לכתיבה ,קריאה && כתיבה. • שרשור לקובץ, דריסת הקובץ. • ניתן לבחור את פורמט הקובץ (בינארי / טקסט) • קריאה / כתיבה לקובץ. • סגירת הקובץ.
פתיחת קובץ voidofstream::open(const char*filename,intmode); voidifstream::open(const char*filename, int mode); • filename– שם הקובץ. • mode– אופן הפתיחה: (ניתן לבחור מספר אפשרויות ע"י התו |). • app– שרשור. • ate– פתח עם הסמן בסוף הקובץ. • in / out– כתיבה / קריאה. • nocreate / noreplace– פתח רק אם קיים \ לא קיים. • trunc– פתח קובץ ריק. • binary– פתח קובץ בינארי (ברירת מחדל: טקסט). • סגירת קובץ – ע"י הפונקציה close().
פונקציות • is_open() / אופרטור ! – האם הקובץ נפתח. • rd_state() – מחזיר iostate עם מצב הקובץ: • הקובץ תקין –goodbit. • הסמן הגיע לסוף של הקובץ –eofbit. • הפעולה הבאה תכשל –faildbit. • הקובץ לא תקין –badbit. • ניתן לבדוק מצב ע"י - fail(), bad() ,good(), oef(). • setstate() – שינוי מצב הקובץ.
דוגמא ofstream file ("tmp.txt"); if (file.is_open()) { //... ios_base::iostate s = file.rdstate(); if (s == ios_base::goodbit) { cout << "good\n"; file.setstate(ios_base::badbit); } s = file.rdstate(); if (s == ios_base::badbit) cout<<"bad\n"; } file.close();
האופרטורים >> ו-<< • מכיוון שהמחלקות <ifstream>, <ofstream>, <fstream> יורשות מ-<istream>, <ostream>, האופרטורים << , >> מועמסים.
tmp.txt This is the first line. This is the second line. דוגמא ofstream ofile ("tmp.txt"); if (ofile.is_open()) { ofile << "This is the first line.\n"; ofile << "This is the second line.\n"; ofile.close(); } else cout << "Can't open file"; ifstream ifile("tmp.txt"); if (ifile) { string s1,s2; getline(ifile, s1); cout << s1 << endl << s2 << endl; } else cout << "Can't open file"; ifile.close();
כתיבה / קריאה • בנוסף לאופרטורים >> , << ניתן להשתמש בפונקציות: • get() / put() – קריאת / כתיבת תו בודד. • getline() – קריאת שורה שלמה. ofstream ofile; ofile.open("tmp.txt"); file << "Hello"; file.put(' '); file << "World!\n"; file.close(); ifstream ifile; ifile.open("tmp.txt"); getline(ifile, s); cout << s << endl; ifile.close(); פלט: Hello World!
הראש הקורא • כמו ב-C, ישנו את הראש הקורא שמתקדם עם כל קריאה / כתיבה. • seekp() / seekg() – הזזת הראש הכותב / הקורא. (put/get) • פרמטרים: • מספר תווים. • נקודת ייחוס (beg , cur , end) string s; ofstream ofile; ofile.open("tmp.txt"); ofile << "Hello World!\n"; ofile.seekp(6, ios::beg); ofile << "Israel!\n"; ofile.close(); ifstream ifile; ifile.open("tmp.txt"); getline(ifile, s); cout << s<<endl; פלט: Hello Israel!
הראש הקורא • כמו ב-C, ישנו את הראש הקורא שמתקדם עם כל קריאה / כתיבה. • tellp() / tellg() – מיקום הראש הכותב / הקורא. (put/get) • פרמטרים: • מספר תווים. • נקודת ייחוס (beg , cur , end) ofstream file; file.open("tmp.txt"); file << "Hello World!\n"; int x = file.tellp(); cout << x << endl; file << "GoodBye World!\n"; x = file.tellp(); cout << x << endl; file.seekp(-5, ios::cur); x = file.tellp(); cout << x << endl; פלט: 14 30 25
קבצים בינאריים • כתיבת n בתים מתוך buffer: • write (const unsigned char* buffer, int n); • קריאת n בתים למערך buffer: • read (const unsigned char* buffer, int n); int main() { int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; ofstream binary_file(“tmp.txt“, ios::out | ios::binary); binary_file.write((char*) arr, sizeof(arr)); binary_file.close(); }
typedef vector<int>::iterator VecItr; voidAbortProgram(char* file) { cerr << "Error open the file: " << file << endl; exit(-1); } דוגמא intmain () { ifstream rFile; ofstream wFile; // open the files rFile.open("input.txt", ios::in); if (!rFile) AbortProgram("input.txt"); wFile.open("output.txt", ios::out); if (!wFile) { rFile.close(); AbortProgram("output.txt"); } // read the data from the file vector <int> iArray; int iNum; while ((rFile >> iNum) && (!rFile.eof())) iArray.push_back(iNum); //sort the vector VecItr first = iArray.begin(); VecItr last = iArray.end(); sort<VecItr>(first, last);
דוגמא // open the files // read the data from the file //sort the vector // write to the output file int iASize = iArray.size(); for (int i = 0; i < iASize; ++i) wFile << "iArray[" << i << "] = “<< iArray[i] << endl; // close the files rFile.close(); wFile.close(); return 0; } input.txt: 6 2 5 3 output.txt: iArray[0]= 2 iArray[1]= 3 iArray[2]= 5 iArray[3]= 6
class Point { private: int m_iX, m_iY; public: Point(): m_iX(0), m_iY(0) {} Point(int X, int Y): m_iX(X), m_iY(Y) {} friend ostream &operator <<(ostream&, Point&); friend istream &operator >>(istream&, Point&); }; ostream& operator <<(ostream &os, Point &p) { os << '(' << p.m_iX << ',' << p.m_iY << ')'; return os; } istream& operator >>(istream &is, Point &p) { is >> p.m_iX >> p.m_iY; return is; } עוד דוגמא
intmain () { ifstream rFile; ofstream wFile; Point p; // open the files rFile.open("input.txt", ios::in); if (!rFile) AbortProgram("input.txt"); rFile >> p; // First 2 numbers are point co-ordinations // read the data from the file vector <int> iArray; int iNum; while ((rFile >> iNum) && (!rFile.eof())) iArray.push_back(iNum); // close the file rFile.close(); עוד דוגמא - המשך
עוד דוגמא - המשך //sort the vector VecItr first = iArray.begin(); VecItr last = iArray.end(); sort<VecItr>(first, last); wFile.open("output.txt", ios::out); if (!wFile) AbortProgram("output.txt"); wFile << "The point is " << p << endl; // write to the output file int iASize = iArray.size(); for (int i = 0; i < iASize; ++i) wFile << "iArray[" << i << "] = “<< iArray[i] << endl; // close the files wFile.close(); return 0; } input.txt: 20 30 1 4 2 5 output.txt: The point is (20,30) iArray[0] = 1 iArray[1] = 2 iArray[2] = 4 iArray[3] = 5
דוגמא נוספת • נרצה לכתוב תוכנית שלוקחת קבצי in וממזגת אותם לקובץ out אחד. in0.txt Daniel 036388 98 in1.txt Almog 853747 83 Meital 305063 64 in2.txt Hofit 123739 79 Maayan 907953 96 Tal-Hen 758945 89 output.txt Daniel 036388 98 Almog 853747 83 Meital 305063 64 Hofit 123739 79 Maayan 907953 96 Tal-Hen 758945 89
דוגמא נוספת int main() { ofstream out_file; ifstream in_file; out_file.open("output.txt"); if (!out_file) cout << "Can not open file\n"; char file[8] = "in0.txt"; for (int i=0; i<9; i++) { file[2] = '0'+i; in_file.open(file); if (!in_file) cout << "Can not open file\n"; string s; while (!in_file.eof()) { getline(in_file, s); out_file << s << endl; } in_file.close(); } //…
exceptions ifstream in_file; in_file.exceptions ( ifstream::eofbit | ifstream::failbit | ifstream::badbit ); try { in_file.open("no_such_file.txt"); } catch (ifstream::failure e) { cout << "exception\n"; exit(1); } try { in_file.open(“file.txt"); while (true) in_file.get(); } catch (ifstream::failure e) { cout << "exception\n"; exit(1); }