290 likes | 443 Views
File I/O. fstream files. File: similar to vector of elements Used for input and output Elements of file can be character (text) struct object (non-text or binary) int double array,. fstream methods. For files, cin.get( obj ); cout.put( obj );
E N D
fstream files • File: similar to vector of elements • Used for input and output • Elements of file can be • character (text) struct • object (non-text or binary) int • double array, ...
fstream methods • For files, cin.get( obj ); cout.put( obj ); • get() extracts one value from input buffer • put() inserts one value into output buffer
Sequential Access Files • File accessed in same order as written • Next input extraction picks up where last input extraction left off. • File is stream of elements • File may be of varying sizes • Limiting (think: cassette tape)
Random Access Files • Read and write fixed-length records that contain fields (like C++ structure or class) • Files can be accessed sequentially • Files can be accessed randomly (think: CDs) • File pointer must be positioned before input extraction operation for random access • Each record logically has relative record number (similar to index of arry, 0..n-1)
Sequential vs. Random Access • Random requires fixed-length records • Can contain characters, strings, ints, floats, struct or object instance • Can be written in • text format (character by character) • non-text (binary; written using same internal format as in memory)
Open Method filePtr.open (filename, access mode) ifstream ifs; ofstream ofs; • Open input file ifs.open (“names.txt”, ios::in); • Open output file ofs.open (“names.txt”, ios::out);
Open Access Modes Mode Description in Open for reading out Open for writing app Open for appending at end binary Opens in binary mode (non-text) to save space (no conversion)
Open Examples • Create file, write to it, and change some data ofs.open(“names.dat”, ios::in | ios::out); • Create file and make changes, all in non-text mode ofs.open(“names.dat”, ios::in | ios::out | ios::binary);
fstream Methods for Random Access • tellg() - returns (in bytes) location of file pointer in input file • tellp() - returns (in bytes) location of file pointer in output file • seekg() - repositions current file pointer in input file • seekp() - repositions current file pointer on output file • If both in and out, use tellg() and seekg()
seekg() Method • Moves the file pointer to a specific point in random-access data file • Format is: file.seekg(longNum, origin) • file - already initialized with open() • longNum - number of bytes to skip • origin - where to begin seeking • seekp() similar for output files
Values for origin C++ name Description ios::beg Beginning of file ios::cur Current file position ios::end End of file (all defined in fstream.h)
Examples of seekg() • Position file pointer at beginning of file ofs.seekg( 0L, ios::beg); 0L (zero L) is constant long integer zero • Moves file pointer zero bytes from beginning of the file
Example program using seekg() to read file twice void main() { char inChar; ifstream inFile; ofstream scrnl; inFile.open(“MYFILE.TXT”,ios::in); scrn.open(“CON”, ios::out); if (!inFile) { cout << “Error opening MYFILE.TXT”; exit(0);} while (inFile >> inChar) scrn << inChar; scrn.close(); inFile.clear(); // reset EOF1 inFile.seekg(0L, ios::begin); // to beginning while (inFile >> inChar) cout << inChar; inFile.close(); } See Fileio1.cpp
seekg() with file of structures or objects • Suppose have file of structures (inventory records) • Want 123rd occurrence of inventory record • Use sizeof() function filePtr.seekg( (123L * sizeof(struct inventory)), ios::beg);
Binary I/O • Requires primitive read and write methods • write (address, size) • read (address, size) • address - pointer to buffer of data (can be array of bytes or structure) • size - number of bytes to transfer; sizeof(datatype) function useful
Example of non-text modewith standard datatypes ofstream outFile; outFile.open(“myfile.dat”, ios::in|ios::out|ios::binary); int data = 30; int A[20]; outFile.write((char *) & data, sizeof(int)); outFile.write((char *) A, 20*sizeof(int)); outFile.seekg(0L, ios::beg); outFile.read((char *) A, 20*sizeof(int));
Example with objects - 1 #include <fstream.h> class person { public: void getData(void); void showData(void); protected: char name[40]; int age; };
Example with objects - 2 void person::getData(void) { cout << “Enter name: “; cin >> name; cout << “Enter age: “; cin >> age; } void person::showData(void) { cout << “Name: “ << name; cout << “Age: “ << age; }
Example with objects - 3 #include <iostream.h> void main(void) //create file of person objects { char ch; person pers; ofstream file; file.open (“PERSON.DAT”, ios::binary); do { cout << “Enter person’s data:”; pers.getData(); file.write((char*) &pers, sizeof(pers)); cout << “Enter another person(y/n)?”; cin >> ch; } while (ch == ‘y’); } Fileio3.ide
Example with objects - 4 #include <iostream.h> void main(void) //read file of person objects { char ch; person pers; ifstream file; file.open (“PERSON.DAT”, ios::binary); while (file.read((char *) &pers, sizeof(pers)) ) { cout << “Person”; pers.showData(); } } Fileio4.ide
Define a random accessnon-text stream class template <class T> class rstream { public: rstream (string& name); int get (unsigned int index, T & value); void put (unsigned int index, T & value); unsigned int length(); protected: fstream theStream; };
rstream constructor template <class T> rstream::rstream (string& name) { // construct an instance of rstream // convert string into C-style pointer variable char * cName = name.c_str(); // open the file for both input and output theStream.open (cName, ios::in | ios::out | ios::binary); }
put method for rstream template <class T> void rstream::put (unsigned int index, T & value) { // place a value into a random access stream // first position the stream theStream.seekg ( sizeof (T)* index ); // then write the value char & valuePtr = (char *) & value; theStream.write (valuePtr, sizeof(T)); }
get method for rstream template <class T> int rstream::get (unsigned int index, T & value) { // read a value from a random access stream // first position the stream theStream.seekg ( sizeof (T)* index ); // then read the value char & valuePtr = (char *) & value; theStream.read (valuePtr, sizeof(T)); // return the number of bytes read return theStream.gcount(); }
length method for rstream template <class T> unsigned int rstream::length ( ) { // return number of elements held in collection // first seek to end theStream.seekg ( 0L, ios::end ); // then divide current byte offset // by size of elements return theStream.tellg() / sizeof(T); }
References • Ford, William and William Topp. 1996. Data structures with C++. Englewood Cliffs: Prentice Hall. • Lafore, Robert. 1995. The Waite Group’s object-oriented programming in C++. Corte Madera, California: Waite Group Press. • Perry, Greg. 1992. C++ programming 101. Sams Publishing.