Transcript Document

We’ve Looked at Basic Input and Output Already
• How to move data into and out of a program
– Using argc and argv to pass command line args
– Using cout to print data out to the terminal
– Using cin to obtain data from the user at run-time
– Using an ifstream to read data in from a file
– Using an ofstream to write data out to a file
• How to move data between strings, basic types
– Using an istringstream to extract int values
– Using an ostringstream to assemble a string
• This module will expand on those ideas
– Towards understanding better how steams work
– Towards using them even more effectively
CSE 332: C++ IO
Example: Moving Data Into and Out of a Struct
// struct, operator declarations (in point2d.h)
struct Point2D {
Point2D (int x, int y);
bool operator< (const Point2D &) const;
int x_;
int y_;
};
// extraction operator(also in point2d.h)
istream & operator>> (istream &, Point2D &);
// insertion operator(also in point2d.h)
ostream & operator<< (ostream &,
const Point2D &);
CSE 332: C++ IO
Defining Stream Operators for a Struct
// operator definitions (in point2d.cpp)
// extraction operator(also in point2d.h)
istream & operator>> (istream &i, Point2D &p) {
i >> p.x_ >> p.y_; // extract both variables
return i;
}
// insertion operator(also in point2d.h)
ostream & operator<< (ostream &o,
const Point2D &p) {
o << p.x_ << " " << p.y_; // space delimited
return o;
}
CSE 332: C++ IO
Now Can Use the Struct with Various Streams
// uses standard io streams
#include <iostream>
using namespace std;
#include "point2d.h"
int main(int, char*[]){
while (true) {
Point2D p(0, 0);
cout << "Please enter 2
coordinates (or hit
Ctrl-C to quit): ";
cin >> p;
cout << endl
<< "You entered "
<< p << endl;
}
return 0;
} CSE 332: C++ IO
// uses string streams
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
#include "point2d.h"
int main(int, char*[]){
Point2D p(0, 0);
string s ("64 81");
istringstream i(s);
i >> p;
ostringstream o;
o << p;
cout << "The string is "
<< o.str() << endl;
return 0;
}
Flushing Streams (and Stream Manipulators)
• An output stream may hold onto data for a while, internally
– E.g., writing chunks of text rather than a character at a time is efficient
– When it writes data out (e.g., to a file, the terminal window, etc.) is
entirely up to the stream, unless you tell it to flush out its buffers
• If a program crashes, any un-flushed stream data is lost
– Terminal output & files are as of last flush, not as of where it crashed
– So, flushing streams reasonably often is an excellent debugging trick
• Can tie an input stream directly to an output stream
– Output stream is then flushed by call to input stream extraction operator
– E.g., my_istream.tie(&my_ostream);
– cout is already tied to cin (useful for prompting the user, getting input)
• Also can flush streams directly using stream manipulators
– E.g., cout << flush; or cout << endl; or cout << unitbuf;
• Other stream manipulators are useful for formatting streams
– Field layout: setwidth, setprecision, etc.
– Display notation: oct, hex, dec, boolalpha, noboolalpha, scientific, etc.
CSE 332: C++ IO
A Few More Useful Details
• Cannot copy or assign stream objects
– Copy construction or assignment syntax using them results
in a compile-time error
• Extraction operator consumes data from input stream
– “Destructive read” that reads a different element each time
– Use a variable if you want to read same value repeatedly
• Need to test streams’ condition states
– E.g., calling the is_open method on a file stream
– E.g., use the stream object in a while or if test
– Insertion and extraction operators return a reference to a
stream object, so can test them too
• File stream destructor calls close automatically
CSE 332: C++ IO