1 / 49

Object Oriented Data Structures CSIS2020

Object Oriented Data Structures CSIS2020. File I/O in C++. Disk File I/O with Streams. Disk files require another set of classes. ifstream for input fstream for both input and output ofstream for output.

gloria
Download Presentation

Object Oriented Data Structures CSIS2020

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Object Oriented Data Structures CSIS2020 File I/O in C++

  2. Disk File I/O with Streams Disk files require another set of classes • ifstream for input • fstream for both input and output • ofstream for output Be careful about mixing the old C functions with C++ streams. They don't always work together gracefully, although there are ways to make them cooperate.

  3. External Drive physical file name data.txt 342659 Creating a Sequential Access File Program A Simple Process in C++

  4. External Drive physical file name data.txt 342659 #include <fstream> Program ifstream inf; //input stream

  5. External Drive physical file name data.txt 342659 #include <fstream> Program ifstream inf; inf.open("a:\data.txt"); //inf the logical file name

  6. External Drive physical file name data.txt 342659 #include <fstream> Program ifstream inf; inf.open("a:\data.txt"); //inf the logical file name int x; inf >> x; while (!inf.eof()){ cout << x; inf >> x; }

  7. External Drive physical file name data.txt 342659 #include <fstream> Program ifstream inf; inf.open("a:\data.txt");//inf the logical file name int x; inf >> x; // priming read while (!inf.eof()){ cout << x; inf >> x; } inf.close();

  8. getline( char* buffer, int size,char delimeter = '\n'); getline( what character array do I store it in?what's the maximum number of characters to read?what indicates the end of the string?) I do not read in the delimiter as part of the character array.

  9. #include <fstream> // for file functions void main() { constint MAX = 80; // size of buffer char buffer[MAX]; // character buffer ifstream infile("TEST.TXT"); // create file for input infile.getline(buffer, MAX); // priming read while( !infile.eof() ) // until end-of-file { cout << buffer << endl; // display itinfile.getline(buffer, MAX); // read a line of text } }

  10. The following material was adapted from Object-Oriented Programming in C++, Second Edition by Robert LaFore, Waite Group Press, 1995

  11. Formatted file I/O - writing The following program writes a character, an integer, a type double, and two strings to a disk file. There is no output to the screen.

  12. #include <fstream> // for file I/O // (includes iostream.h) void main() { char ch = 'x'; int j = 77; double d = 6.02; char str1[] = "Kafka"; // strings without char str2[] = "Proust"; // embedded spaces ofstream outfile("fdata.txt"); // create ofstream object outfile << ch // insert (write) data << j << ' ' // needs space between numbers << d << str1 << ' ' // needs spaces between strings << str2; }

  13. Formatted I/O - Reading Data Data can be read back in by using an ifstream object, initialized to the name of the object. The file is automatically opened when the object is created. We can then read from it using the extraction (>>) operator.

  14. #include <fstream.h> // for file functions void main() { ofstream outfile("TEST.TXT"); // create file for output // send text to file outfile << "I fear thee, ancient Mariner!\n"; outfile << "I fear thy skinny hand\n"; outfile << "And thou art long, and lank, and brown,\n"; outfile << "As is the ribbed sea sand.\n"; }

  15. Binary I/O Storing numeric data as text can become costly. For example: "31543" would use five bytes if stored as text, 2 bytes if stored as an integer. Numeric data may be stored as it is represented in RAM if the file is declared a binary file

  16. Binary I/O write()- a member of ostream read()- a member of istream These functions merely transfer a buffer full of bytes from and to a disk file. The parameters are the address of the data buffer and its length. The address must be cast to type char, and the length is the length in bytes (characters), not the number of data items in the buffer.

  17. #include <fstream> // for file functions constint MAX = 100; // size of buffer int buff[MAX]; // buffer for integers void main(){ for(int j=0; j<MAX; j++) // fill buffer with data buff[j] = j; // (0, 1, 2, ...) ofstream os("edata.dat", ios::binary); // create out stream os.write( (char*)buff, MAX*sizeof(int) ); // write to it os.close(); // must close it for(j=0; j<MAX; j++) // erase buffer buff[j] = 0; ifstream is("edata.dat", ios::binary); // create input stream is.read( (char*)buff, MAX*sizeof(int) ); // read from it for(j=0; j<MAX; j++) // check data if( buff[j] != j ) { cerr << "\nData is incorrect"; return; } cout << "\nData is correct"; }

  18. Closing a File When files go out of scope, they are automatically closed. However, if it is necessary to change from a read mode to a write mode, the file must be explicitly closed, using the close()member function.

  19. fstream class • Can be used for both reading and writing • You must be careful to close the file between reading and writing • Can manipulate both the get and the put pointer (be careful, these are really the same pointer!!!)

  20. #include <fstream> // for file functions class person // class of persons { public: void showData(void) // display person's data { cout << "\n Name: " << name; cout << "\n Age: " << age; } void getData(void) // get person's data { cout << "Enter name: "; cin >> name; cout << "Enter age: "; cin >> age; } protected: char name[40]; // person's name int age; // person's age };

  21. void main(void){ char ch; person pers; // create person object fstream file; // create input/output file // open for append file.open("PERSON.DAT", ios::app | ios::out | ios::in | ios::binary ); do { // data from user to file cout << "\nEnter person's data:"; pers.getData(); // get one person's data then write to file file.write( (char*)&pers, sizeof(pers) ); cout << "Enter another person (y/n)? "; cin >> ch; } while(ch=='y'); // quit on 'n' file.seekg(0); // reset to start of file

  22. file.seekg(0); // reset to start of file file.read( (char*)&pers, sizeof(pers) ); // read first person while( !file.eof() ) // quit on EOF { cout << "\nPerson:"; // display person pers.showData(); // read another file.read( (char*)&pers, sizeof(pers) ); // person } }

  23. open() In the examples thus far, the files have been open for input or open for output. (exclusive or) If you wanted to switch from one mode to the other, the file first had to be closed. It is possible to have a file open for input and output simultaneously. There are several options available for the modes.

  24. Mode bit Result in Open for reading (default for ifstream) out Open for writing (default for ofstream) ate Start reading or writing at end of file app Start writing at end of file trunc Truncate file to zero length if it exists nocreate Error when opening if file does not already exist noreplace Error when opening for output if file already exists, unless ate or app is set binary Open file in binary (not text) mode

  25. Using mode bits It is possible to combine multiple mode bits in the same open statement. Infile.open(“myFile”, ios::append | ios::binary | ios::in | ios::out); This allows the file to be opened for both input and output, says that it will be a binary file and new data will only be added to the end of the file.

  26. File Pointers • get pointer (a.k.a current get position) • put pointer (a.k.a current put position)

  27. File Pointers • get pointer (a.k.a current get position) • put pointer (a.k.a current put position) Explicitly controlled with: seekg()and tellg()(input) seekp()andtellp()(output)

  28. File Pointer Offsets seekg(0); // beginning of file seekg(30); // 30 bytes from beginning of file seekp(-10, ios::end); // 10 bytes before eof

  29. void main(void){ person pers; // create person object ifstream infile; // create input file infile.open("PERSON.DAT", ios::binary); // open file infile.seekg(0, ios::end); // go to 0 bytes from end int endposition = infile.tellg(); // find where we are int n = endposition / sizeof(person); // number of persons cout << "\nThere are " << n << " persons in file"; cout << "\nEnter person number: "; cin >> n; int position = (n-1) * sizeof(person); // offset infile.seekg(position); // bytes from begin // read one person infile.read( (char*)&pers, sizeof(pers) ); pers.showData(); // display the person }

  30. Error Handling in File I/O Reacting to errors

  31. #include <fstream.h> // for file streams #include <process.h> // for exit() const int MAX = 1000; int buff[MAX]; void main(){ for(int j=0; j<MAX; j++) // fill buffer with data buff[j] = j; ofstream os; // create output stream // open it os.open("a:edata.dat", ios::trunc | ios::binary); if(!os) { cerr << "\nCould not open output file"; exit(1);} cout << "\nWriting..."; // write buffer to it os.write( (char*)buff, MAX*sizeof(int) ); if(!os) { cerr << "\nCould not write to file"; exit(1); } os.close(); // must close it

  32. for(j=0; j<MAX; j++) // clear buffer buff[j] = 0; ifstream is; // create input stream is.open("a:edata.dat", ios::binary); if(!is) { cerr << "\nCould not open input file"; exit(1); } cout << "\nReading..."; // read file is.read( (char*)buff, MAX*sizeof(int) ); if(!is) { cerr << "\nCould not read from file"; exit(1); } for(j=0; j<MAX; j++) // check data if( buff[j] != j ) { cerr << "\nData is incorrect"; exit(1); } cout << "\nData is correct"; }

  33. #include <fstream.h> // for file functions void main() { ifstream file; file.open("GROUP.DAT", ios::nocreate); if( !file ) cout << "\nCan't open GROUP.DAT"; else cout << "\nFile opened successfully."; cout << "\nfile = " << file; cout << "\nError state = " << file.rdstate(); cout << "\ngood() = " << file.good(); cout << "\neof() = " << file.eof(); cout << "\nfail() = " << file.fail(); cout << "\nbad() = " << file.bad(); file.close(); }

  34. File I/O with Member Functions Objects that Read and Write Themselves

  35. classperson// class of persons { public: void showData(void) // display person's data { cout << "\n Name: " << name; cout << "\n Age: " << age; } void getData(void) // get person's data { cout << "Enter name: "; cin >> name; cout << "Enter age: "; cin >> age; } voiddiskIn(int); // read from file voiddiskOut(); // write to file staticintdiskCount(); // return number of persons in file protected: char name[40]; // person's name int age; // person's age };

  36. void person::diskIn(int pn){ // read person number pn from file ifstream infile; // make stream infile.open("PERSON.DAT", ios::binary); // open it infile.seekg( pn*sizeof(person) ); // move file ptr infile.read((char*)this, sizeof(*this)); // read one person } void person::diskOut(){ // write person to end of file ofstream outfile; // make stream // open it outfile.open("PERSON.DAT", ios::app | ios::binary); outfile.write( (char*)this, sizeof(*this) ); // write to it } int person::diskCount() { // return number of persons in file ifstream infile; infile.open("PERSON.DAT", ios::binary); infile.seekg(0, ios::end); // go to 0 bytes from end // calculate number of persons return (int)infile.tellg() / sizeof(person); }

  37. void main(void){ person p; // make an empty person char ch; do { // save persons to disk cout << "\nEnter data for person:"; p.getData(); // get data p.diskOut(); // write to disk cout << "Do another (y/n)? "; cin >> ch; } while(ch=='y'); // until user enters 'n' int n = person::diskCount(); // how many persons in file? cout << "\nThere are " << n << " persons in file"; for(int j=0; j<n; j++) { // for each one, cout << "\nPerson #" << j; p.diskIn(j); // read person from disk p.showData(); // display person } }

  38. File I/O with Member Functions Classes that Read and Write Themselves use the this pointer

  39. class SomeType{public:static int n;static vector<SomeType *>data;private:static void read();static void write();}

  40. void SomeType::read(){ ifstream inf; inf.open(“dataFile”, ios::binary);if(!inf) {cout<<“Can’t open file”; return;} • n=0; • data[n] = new SomeType(); inf.read( char*) data[n], sizeof(SomeType) ); n++; • while(!eof()) { data[n] = new SomeType(); inf.read( char*) data[n], sizeof(SomeType) ); n++; } • }

  41. void SomeType::write(){ ifstream ouf; inf.open(“dataFile”, ios::binary | ios::truncate);if(!ouf) {cout<<“Can’t open file”; return;} • for(int j=0; j<n; j++) { out.write( (char*) (data[j]), sizeof(SomeType); } • }

  42. classemployee { // employee class public: virtual void getdata(){ cout << "\n Enter last name: "; cin >> name; cout << " Enter number: "; cin >> number; } virtual void putdata() cout << "\n Name: " << name; cout << "\n Number: " << number; } virtual employee_type get_type(); // get type static void add(); // add an employee static void display(); // display all employees static void read(); // read from disk file static void write(); // write to disk file private: char name[LEN]; // employee name unsigned long number; // employee number static int n; // current number of employees static employee* arrap[]; // array of ptrs to emps };

  43. Overloading Extractors When we develop our own data types, we can overload the extraction operator (>>) and the insertion operator (<<) to work with our new data types and with cin and cout. It is also possible to overload them so that they work with disk files.

  44. Overloading for cout and cin Overloading the two operators is done in a similar fashion. The operators take two parameters, passed by reference. cin istream& operator>> (istream& s, Distance& d) The overloaded operator takes input from the operator s and puts it in the member data d. In this example, s is a reference for cin and d is a reference for a variable of type Distance.

  45. Overloading for cout and cin cout ostream& operator<< (ostream& s, Distance& d) This overloaded operator takes input from the member data d and places it on the outpust stream s. In this example, s is a reference for cout and d is a reference for a variable of type Distance.

  46. Overloading for cout and cin The operator<<() and operator>>() functions must be friends of the Distance class, since the istream and ostream objects appear on the left side of the operator.

  47. class Distance { // English Distance class public: Distance() // constructor (no args) { feet = 0; inches = 0.0; } Distance(int ft, float in) // constructor (two args) { feet = ft; inches = in; } friend istream& operator>>(istream& s, Distance& d); friend ostream& operator<<(ostream& s, Distance& d); private: int feet; float inches; }; istream& operator >>(istream& s, Distance& d){ // get Distance cout << "\nEnter feet: "; s >> d.feet; // using cout << "Enter inches: "; s >> d.inches; // overloaded return s; // >> operator } ostream& operator <<(ostream& s, Distance& d){ // get Distance s << d.feet << "\'-" << d.inches << '\"'; return s; // using overloaded << operator }

  48. Overloading for Files Only a few minor modifications are needed to overload the insertion and extraction operators for file I/O. Note that the same format is used, replacing cin and cout with the logical file name.

  49. File I/O

More Related