Presentation is loading. Please wait.

Presentation is loading. Please wait.

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

Similar presentations


Presentation on theme: "1 Object Oriented Data Structures CSIS2020 File I/O in C++"— Presentation transcript:

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

2 Disk File I/O with Streams ifstream for input fstream for both input and output ofstream for output Disk files require another set of classes 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 Creating a Sequential Access File Program A Simple Process in C++ External Drive data.txt physical file name 34 26 59

4 Program ifstream inf; //input stream External Drive data.txt physical file name 34 26 59 #include

5 Program ifstream inf; inf.open("a:\data.txt"); //inf the logical file name External Drive data.txt physical file name 34 26 59 #include

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

7 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(); External Drive data.txt physical file name 34 26 59 #include

8 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 // for file functions void main() { const int 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 it infile.getline(buffer, MAX); // read a line of text }

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

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 // 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 // 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 // for file functions const int 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 // 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 > name; cout > 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 bitResult 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 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() and tellp() (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 // for file streams #include // 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 // 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 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 > name; cout > age; } void diskIn(int); // read from file void diskOut(); // write to file static int diskCount(); // 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 39 class SomeType { public: static int n; static vector data; private: static void read(); static void write(); }

40 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 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 class employee { // employee class public : virtual void getdata(){ cout > name; cout > 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 >() 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 > d.feet; // using cout > 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 49 File I/O


Download ppt "1 Object Oriented Data Structures CSIS2020 File I/O in C++"

Similar presentations


Ads by Google