CSCI 333 Data Structures I/O with C++ 20 October, 2003
C++ Stream I/O hierarchy ios istream ostream iostream ifstream multiple inheritance virtual base class virtual base class fstream ofstream
ios class Formatting –Width of field, base of numbers State –Open, closed, end-of-file, failed Constants –Open for read/write/append Buffering –Using streambuf class
ANSI C++ ios To support internationalization –ios is a template of basic_ios –Specialized for character set But western programmers don’t worry –Except when looking at the documentation
ios flags for opening files ios::in Open for input ios::out Open for output ios::app Append to file ios::trunc Truncate file ios::nocreate File if file doesn’t exist ios::noreplace Fail if file exists
ios state methods F.good() No errors F.fail() Failure, stream usable F.bad() Failure, stream not usable F.eof() End-of-file !F!F Failed or bad
ios formatting methods F.setw(int) Sets width, returns the stream F.width(int) Sets width returns current width F.fill(char) Sets fill character returns current fill
ios flags for moving in files ios::beg Move relative to beginning of file ios::cur Move relative to current position ios::end Move relative to end of file
istream class Stream input class Read from files –to all sorts of variables Seek to arbitrary file position Templated in ANSI C++ –from basic_istream
Some istream methods F >> x Extract from stream F.read(buff, n) Extract into buffer F.seekg(newPos) Move get pointer F.seekg(nP,skpDr) Move get pointer, relative to seek direction F.tellg() Returns get pointer
Some ostream methods F << x Insert into stream F.write(buff, n) Insert from buffer F.seekp(newPos) Move put pointer F.seekp(nP,skpDr) Move put pointer, relative to seek direction F.tellp() Returns put pointer
The iostream methods Multiple inheritence –istream –ostream Single ios subclass –Since ios is a virtual subclass
The standard stream s cin Standard input cout Standard output cerr Standard error
The fstream methods Most inherited from *stream methods – fstream F ; – fstream F(filename, flags) ; –F.open(filename, flags) ; –F.close() ;
// Opening and closing with ifstream and ofstream #include using namespace std ; int main(int argc, char *argv[]) { ifstream RStream ; ofstream WStream ; RStream.open(argv[1]) ; if (RStream.bad()) cerr << "Unable to read " << argv[1] << endl ; RStream.close() ; WStream.open(argv[1]) ; if (WStream.bad()) cerr << "Unable to write " << argv[1] << endl ; WStream.close() ; }
// Opening and closing with fstream #include using namespace std ; int main(int argc, char *argv[]) { fstream RWStream ; RWStream.open(argv[1], ios::in) ; if (RWStream.bad()) cerr << "Unable to read " << argv[1] << endl ; RWStream.close() ; RWStream.open(argv[1], ios::out) ; if (RWStream.bad()) cerr << "Unable to write " << argv[1] << endl ; RWStream.close() ; }
// Silly file updates #include using namespace std ; int main(int argc, char *argv[]) { fstream RWStream ; RWStream.open(argv[1], ios::in | ios::out | ios::binary) ; if (RWStream.bad()) cerr << "Unable to read or write" << argv[1] << endl ; else { char buff[7] ; // Read from characters 7 to 13 RWStream.seekg(7, ios::beg) ; RWStream.read(buff, 7) ; // Write to characters 14 to 20 RWStream.seekp(14, ios::beg) ; RWStream.write(buff, 7) ; RWStream.close() ; }
// Reverse a file #include using namespace std ; int main(int argc, char *argv[]) { fstream RWStream ; RWStream.open(argv[1], ios::in | ios::out | ios::binary) ; if (RWStream.bad()) cerr << "Unable to read or write" << argv[1] << endl ; else { char buffFront[1] ; // extremely inefficient char buffRear[1] ; RWStream.seekp(0, ios::end) ; int fileSize = RWStream.tellp() ; for (int i=0; i<fileSize/2; ++i) { RWStream.seekg(i, ios::beg) ; RWStream.read(buffFront, 1) ; RWStream.seekg(fileSize-i-1, ios::beg) ; RWStream.read(buffRear, 1) ; RWStream.seekp(i, ios::beg) ; RWStream.write(buffRear, 1) ; RWStream.seekp(fileSize-i-1, ios::beg) ; RWStream.write(buffFront, 1) ; } RWStream.close() ; }
// writing numbers in ASCII and binary #include using namespace std ; int main(int argc, char *argv[]) { ofstream WStream ; WStream.open(argv[1], ios::binary) ; if (WStream.bad()) cerr << "Unable to write" << argv[1] << endl ; else { for (int i=333; i<343; ++i) WStream << i ; for (int i=333; i<343; ++i) WStream.write((char *)&i, sizeof(i)) ; } WStream.close() ; }
// formatted I/O with ios methods #include using namespace std ; int main(int argc, char *argv[]) { cout.fill('0') ; for (int i=0; i<100; ++i) { cout.width(2) ; cout << i ; cout.width(4) ; cout << i*i << endl ; }
// formatting with io manipulators #include using namespace std ; int main(int argc, char *argv[]) { cout.fill('0') ; for (int i=0; i<100; ++i) cout << setw(2) << i << " " << setw(4) << i*i << endl ; }
// Reading integers or characters #include using namespace std ; int main(int argc, char *argv[]) { int i ; cin >> i ; if (cin.fail()) { cin.clear() ; char c ; cin >> c ; if (cin.fail()) cout << "Failure on I/O" ; else cout << "Read character '" << c << "'" << endl ; } else cout << "Read integer " << i << endl ; }
// Summing integers #include using namespace std ; int main(int argc, char *argv[]) { int i ; int sum = 0 ; while(cin >> i && cin.good()) sum += i ; cout << "Total = " << sum << endl ; }
#include using namespace std ; #define INBUFFSIZE 4096 int main(int argc, char *argv[]) { int sum = 0 ; char inLine[INBUFFSIZE+1] ; while (cin.getline(inLine, INBUFFSIZE) && cin.gcount()) { int lineSum = 0 ; int i ; istringstream lineStream(inLine) ; while (lineStream>>i && lineStream.good()) lineSum += i ; if (lineStream.eof()) sum += lineSum ; else cerr << "Ignoring bad input line: " << inLine << endl ; } cout << "Sum = " << sum << endl; }