Download presentation
Presentation is loading. Please wait.
1
chapter 8 CS 3370 – C++ I/O Classes
2
Key I/O Classes istream ostream cin is an istream Subclasses:
ifstream for files istringstream for parsing strings ostream cout and cerr are ostreams ofstream for files ostringstream for building strings
3
Stream Limitations Streams cannot be: You must pass them by reference
copied assigned You must pass them by reference This is a Good Thing they are large objects there should only be one cin, cout, etc.
4
Stream States eof (eofbit) fail (failbit) bad (badbit) good
the end of an input stream has been encountered fail (failbit) operation failed (e.g., invalid data found in an input stream) also set on end-of-stream (eof) a recoverable error bad (badbit) corrupted stream (e.g., physical failure; this is unrecoverable) very rare good none of the above bits are set the stream is valid and usable
5
Inspecting the Stream State
Member functions: str.eof( ) (remember, failbit will also be set) str.fail( ) (true if either failbit or badbit is set) str.bad( ) str.good( ) Conversion to bool: if (str)… or while (str)… same as: if (!str.fail( )) or while (!str.fail( )) in other words, str.good( ) is true
6
Consequence of failbit
The stream is inoperable Any subsequent stream requests will be ignored To recover from an I/O error: clear all the bits to make the stream operable again call str.clear( ) report the error to the user and move on Example: checking console input see readstuff.cpp
7
failbit and User-defined Input Ops
Your own input operators must behave in the expected way Set the failbit when invalid data is in the stream Example: a Date class input operator
8
Date Input (numeric month-day-year)
istream& operator>>(istream& is, Date& d) { is >> d.month; char dash; is >> dash; if(dash != '-') { is.unget(); is.setstate(ios::failbit); // Input disabled return is; } is >> d.day; is.setstate(ios::failbit); return is; is >> d.year; After setting failbit everything is a NOP. Carefully go through all cases here, including possible EOF.
9
An Input “Gotcha” Reading a string after reading an int
if the string is on the next line, you have a problem… After reading the int, the newline character ('\n') is still there You will get an empty string! What to do?
10
Options 1) Read each line as a string and parse
using getline and istringstream we did this in readstuff.cpp a few slides back 2) Read the int, then eat through the newline using str.ignore( ) #include <limits> … str >> n; str.ignore(numeric_limits<streamsize>::max(),‘\n’);
11
String Streams istringstream ostringstream See sstream.cpp
allows you read from a string as if it is a stream (using >>) ostringstream you build a string by writing objects to an ostringstream (using <<) to get the result string, call: string s = strm.str( ) , or strm.str(s) (to overwrite an existing string, s) See sstream.cpp
12
String Conversions We can write generic functions that convert objects to and from strings Requires streamable types: types that have operator<< and operator>> Strategy: toString will write to a ostringstream fromString will read from a istringstream
13
toString template<class T> string toString(const T& t) {
ostringstream os; os << t; return os.str(); } … double x = 7.2; string s(toString(x));
14
fromString template<class T> T fromString(const string& s) {
istringstream is(s); T t; is >> t; return t; } … double y = fromString<double>(s);
15
std::to_string #include <iostream> #include <sstream>
#include <string> // Defines std::to_string using namespace std; template<class T> string toString(const T& t) { ostringstream os; os << t; return os.str(); } int main() { double x = 7.2; cout << to_string(x) << endl; // cout << toString(x) << endl; // 7.2 MinGW doesn’t support this yet.
16
Handy Input Functions get getline ignore unget peek
17
get get( ) get(char& c) get(char* s, int n, char delim = ‘\n’)
returns the next character, or -1 whitespace included (doesn’t skip whitespace) get(char& c) puts the character read in c returns the stream get(char* s, int n, char delim = ‘\n’) reads n characters or up to delim leaves delim in stream!
18
getline Two versions getline(char* s, int n, char delim = ‘\n’)
reads and discards delim (different from get, which leaves delim) returns the stream getline(istream& is, string& s, char delim = ‘\n’) uses a string, not a char* declared in <string> preferred over the previous overload of getline above
19
ignore Discards characters ignore(int n = 1, int delim = eof( ))
returns stream For a large n, use: std::numeric_limits<streamsize>::max()
20
unget, peek unget() peek()
Moves the stream’s “get pointer” back one The next input op therefore re-reads the previous character peek() Returns the next character without moving the get pointer Can only call once without an intervening read! So you can’t back up multiple characters with unget unget and putback must not be called multiple times without intervening read ops.
21
File I/O The <fstream> constructors automatically open the file
you rarely need to use .open( ) explicitly The <fstream> destructors automatically close the file ditto You should use this pattern in your own classes constructors allocate the resource destructors de-allocate it RAII: “Resource Acquisition Is Initialization”
22
File Open Modes Sometimes you need special file processing
Note how app is special – previous contents are not disturbed. Handy for log files. You must specify in or out when you use the other 4.
23
Default Modes For ostream:
ios::out & ios::trunc ios::app and ios::trunc are mutually exclusive ios::app is the only way to preserve existing data in an output file ios::ate is only useful for files opened for both input and output using fstream with both ios::in and ios::out ios:ate will truncate an ofstream
24
Binary Mode Has nothing to do with writing raw data
using ostream::write( ) Exists only for a Windows oddity (WYSINWYG :-) writing '\n' really writes "\r\n" reading "\r\n" only returns the '\n' Binary turns off this special processing data read into memory is identical to the data in the file Use binary mode for file positioning with the seek and tell member functions
25
Stream Positioning Can move around in a stream
except when using the console, of course Using functions seekp( ), seekg( ) seekp( ) seeks in the output buffer (p = “put”) seekg( ) seeks in the input buffer (g = “get”) Simultaneous I/O streams share the same buffer File streams keep the put/get pointers together so the read and write positions are identical In string streams they’re independent
26
Files With Fixed-length Records
Often used by databases (and Program 4) can access records randomly Fields must have only built-in data numbers, C-style strings, static arrays no pointers! requires binary mode Use the write and read member functions See employeedb.cpp
27
Formatted I/O Section 17.5 Set flags on streams Manipulators
for width, precision, etc. setf, unsetf Manipulators shortcuts for calling setf/unsetf endl hex, dec, oct setw(n), …
28
Output Formatting Can set stream attributes Use setf( ) and unsetf( )
width, fill character, alignment, numeric base, floating-point format, decimal precision, etc. Use setf( ) and unsetf( ) Example: format.cpp, format.out
29
Stream Buffers The data area(s) held by the stream
Can access via the function rdbuf( ) A “Way Station” for data en route We usually don’t use rdbuf Two cool features: rdbuf1.cpp, rdbuf2.cpp
30
Manipulators A shorthand for setting/unsetting stream attributes
dec, hex, endl, flush Achieved via a special overload convention manipulators are functions when inserted into the stream, the following function is called: ostream& ostream::operator<<(ostream& (*pf)(ostream&)) { return pf(*this); } The function pf should do its work and then return the stream
31
Creating Your Own Manipulator
#include <iostream> Define a function with the required signature (below) Do your work and return the stream: ostream& nl(ostream& os) { return os << '\n'; } int main() { cout << "newlines" << nl << "between" << nl << "each" << nl << "word" << nl; cout << nl becomes… cout.operator<<(nl), which executes nl(cout), which executes cout << ‘\n’
32
Manipulators with Arguments
setw(n), setfill(c), setprecision(n), etc. Must include <iomanip> for these Example: manips.cpp, manips.out Difficult to implement your own not portable Use Effectors instead (see next slide)
33
Effectors Create a class whose constructor formats a string according to its purpose That class also must provide an operator<< Example: effector.cpp
Similar presentations
© 2024 SlidePlayer.com Inc.
All rights reserved.