330 likes | 433 Views
EC-241 Object-Oriented Programming. LECTURE 12. C++ File I /O. A stream is a general name given to a flow of data. Disk file I/O is a special case of the general I/O system The classes used specifically for Disk file I/O are declared in the file FSTREAM. Stream class hierarchy (simplified).
E N D
EC-241 Object-Oriented Programming LECTURE 12
C++ File I/O • A stream is a general name given to a flow of data. • Disk file I/O is a special case of the general I/O system • The classes used specifically for Disk file I/O are declared in the file FSTREAM
Stream class hierarchy (simplified) ios ios ios ios ostream istream ios ios ios ofstream ifstream iostream ios fstream
Disk File I/O with Streams • Three relevant classes: • ifstream for input // ifstream in; • ofstream for output // ofstream out; • fstream for both input and output // fstreamio;
Opening and Closing a file • void ifstream::open(const char *filename, ios::openmode mode= ios::in) • void ofstream::open(const char *filename, ios::openmode mode= ios::out | ios::trunc) • void fstream::open(const char *filename, ios::openmode mode= ios::in | ios::out) • ios::in • ios::out • ios::binary • ios::trunc • Ios::app • Ifstream io(”my file”); • io.close();
Reading and writing Text Files • Use << and >> operators the same way you do when performing console I/O, except that instead of using cin, cout substitue a string that is linked to a file
Writing and Reading #include <iostream> # include <fstream> using namespace std; void main() { ofstream out("test.txt"); out<<"Computer "<<28.9; out<<"Laptop "<<59.5; } #include <iostream> # include <fstream> #include <string> using namespace std; void main() { string item; float price; ifstream in("test.txt"); in>>item>>price; cout<<item<<" "<<price<<endl; in>>item>>price; cout<<item<<" "<<price<<endl; }
Formatted File I/O • Numbers are stored as a series of characters • E.g. 6.02 is stored as character ‘6’, followed by chars ‘.’, ‘0’, and ‘2’. • Inefficient, but easy to implement
Writing (Formatted) Data # include <fstream> #include <string> … void main() { char ch=‘x’; int i=77; double d=6.02; string str1=“Kafka”, str2=“Proust”; //strings without embedded spaces ofstreamoutfile(“fdata.txt”); outfile<<ch <<i <<‘ ‘ //needs space btw numbers <<d <<str1 <<‘ ‘ //needs space btw strings <<str2; }
Reading (Formatted) Data void main() { char ch; inti; double d; string str1, str2; ifstreaminfile(“fdata.txt”); infile>>ch>>i>>d>>str1>>str2; cout<<ch<<endl <<i<<endl <<d<<endl <<str1<<endl <<str2<<endl; }
Strings with Embedded Blanks //file output … void main() { ofstreamoutfile(“test.txt”); 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”; }
Strings with Embedded Blanks //file input … void main() { constint MAX=100; char buffer[MAX]; ifstreaminfile(“test.txt”); while (!infile.eof()) // until eof encountered { infile.getline(buffer, MAX); cout<<buffer<<endl; } }
Unformatted and Binary I/O • In binary I/O numbers are stored as they are in the memory rather than as strings of characters • In binary I/O int is always stored in 4 bytes, whereas its text version might be ”234567”
Unformatted and Binary I/O • put() and get() can be used to output and input singal characters • istream &get(char &ch) • ostream &put(char ch) • read() and write() reads and writes block of binary data • istream &read(char *buf, streamsize num) • ostream &write(const char *buf, streamsize num)
Unformatted and Binary I/O constint MAX=100; int buff[MAX]; void main() { for (int j=0; j<MAX; j++) buff[j]=j; ofstreamos(“edata.dat”, ios::binary); os.write(reinterpret_cast<char*> (buff), MAX*sizeof(int)); os.close();
Binary I/O for (int j=0; j<MAX; j++) buff[j]=0; ifstream is(“edata.dat”, ios::binary); is.read(reinterpret_cast<char*> (buff), MAX*sizeof(int)); for (int j=0; j<MAX; j++) if (buff[j]!=j) cout<<“Data is incorrect\n”; }
Object I/O //oper.cpp class person { protected: char name[80]; short age; public: void getData() { cin>>name; cin>>age; } };
Object I/O: Writing an object void main() { person per; per.getData(); ofstreamoutfile(“PERSON.DAT”, ios::binary); outfile.write(reinterpret_cast<char *> (&per), sizeof(per)); }
Object I/O: Reading an Object //iper.cpp class person { protected: char name[80]; short age; public: void showData() { cout<<name; cout<<age; } };
Object I/O: Reading an object void main() { person per; ifstreaminfile(“PERSON.DAT”, ios::binary); infile.read(reinterpret_cast<char *> (&per), sizeof(per)); per.showData(); }
I/O with Multiple Objects class person { protected: char name[80]; short age; public: void getData() { cin>>name; cin>>age; } void showData() { cout<<name; cout<<age; } };
void main() { char ch; person per; fstream file; //create an i/o file file.open(“GROUP.DAT”, ios::app|ios::out|ios::in|ios::binary); do { cout<<“\nEnter person’s data:”; per.getData(); file.write(reinterpret_cast<char*>(&per), sizeof(per)); cout<<“Enter another person (y/n) ? “; cin>>ch; } while (ch==‘y’);
file.seekg(0); file.read(reinterpret_cast<char*>(&per), sizeof(per)); while (!file.eof()) { cout<<“\n Person:” ; per.showData(); file.read(reinterpret_cast<char*>(&per), sizeof(per)); } }
Accessing Non-Adjacent Locations • File Position Pointer • Byte number of next byte in the file to be read or written • For ifstream: get pointer • For ofstream: put pointer • Functions to position the file position pointer at desired byte: • For ifstream: seekg (seek get) • For ofstream: seekp(seek put)
Examples: Accessing Non-Adjacent Locations ifstreaminfile(“data.dat”); //position to the nth byte of file (n is any int) infile.seekg(n, ios::beg); //offset from beginning (default) //position n bytes forward from current position infile.seekg(n, ios::cur); //position n bytes back from end of file infile.seekg(n, ios::end); //position at end of file infile.seekg(0, ios::end);
Random Access void main() { person per; ifstreaminfile; infile.open(“GROUP.DAT”, ios::in|ios::binary); infile.seekg(0, ios::end); //reach end intendposition=infile.tellg(); int n=endposition/sizeof(person); //total //number of persons in the file cout<<“There are “<<n<<“persons in the file”;
cout<<“\nEnter person number to read: “; cin>>n; int position= (n-1)*sizeof(person); infile.seekg(position); infile.read(reinterpret_cast<char*> (&per), sizeof(per)); per.showData(); }
Objects that Read and Write Themselves class person { protected: char name[80]; short age; public: void getData() { cin>>name>>age; } void showData() { cout<<name<<age;} void diskIn(int); //read from file void diskOut(); //write to file static intdiskCount(); //return number of persons in file //Note: static functions can be called without any object };
void person::diskIn(intpn) { ifstreaminfile; infile.open(“PERSFILE.DAT”, ios::binary); infile.seekg(pn*sizeof(person)); infile.read((char*)this, sizeof(*this)); }
void person::diskOut() { ofstreamoutfile; outfile.open(“PERSFILE.DAT”, ios::app|ios::binary); outfile.write((char*)this, sizeof(*this)); }
int person::diskCount() { ifstreaminfile; infile.open(“PERSFILE.DAT”, ios::binary); infile.seekg(0, ios::end); return (int)infile.tellg()/sizeof(person); }
void main() { person p; char ch; do { cout<<“\nEnter person’s data:”; p.getData(); p.diskOut(); cout<<“Enter another person (y/n) ? “; cin>>ch; } while (ch==‘y’); int n=person::diskCount(); cout<<“There are “<<n<<“persons in the file”;
for (int j=0; j<n; j++) { cout<<“\n Person “ <<j; p.diskIn(j); p.showData(); } }