Upload
martin-baldwin
View
233
Download
1
Tags:
Embed Size (px)
Citation preview
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 );
• 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 fileifs.open (“names.txt”, ios::in);
• Open output fileofs.open (“names.txt”, ios::out);
Open Access Modes
Mode Descriptionin Open for readingout Open for writingapp Open for appending at endbinary 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 Descriptionios::beg Beginning of fileios::cur Current file positionios::end End of file
(all defined in fstream.h)
Examples of seekg()
• Position file pointer at beginning of fileofs.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 twicevoid 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() functionfilePtr.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 mode
with standard datatypesofstream 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 access
non-text stream classtemplate <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.