Input/Output in C++
C++ has a very simple system for I/O.
- The bit shift operators
<<and>>are overloaded to perform output (stream insertion) and input (stream extraction), respectively - C++ overloads meanings of other operators as well, e.g. "
+" can concatenate strings (more on this later) - Stream extraction operator
>>will read into any primitive data type; type read is based on type of variable, not a format string - Uses all forms of whitespace to tokenize
- Invalid input (wrong data type) puts stream in error condition
-
<<and>>are binary operators, result is modified stream, allows chaining - Using
cinas loop control: value istrueboolean if stream is in good state,falseotherwise:
while (cin >> n) process(n);
while (cin.get(ch)) process(ch); - Output buffer automatically flushed with
\n,endl,read, or buffer full std::cerris a third stream used mainly for error or debugging output
Here are some examples:
std::cin >> thing1 >> thing2; // read thing1 then thing2 from cin, standard input stream
std::cout << thing1 << thing2; // write thing1 then thing2 to cout, standard output stream (no spaces included)
std::cout << '\n' << std::endl; // output newline, newline and flush buffer
std::cin.get(ch); // read one character
// equivalent form if appropriate using declarations were given:
cin >> thing1 >> thing2;
cout << thing1 << thing2;
cout << '\n' << endl;
cin.get(ch);
Files in C++
Stream Classes
Inheritance is used for different file access modalities, where ‘f’ streams are for files (ifstream, ofstream, fstream). C++ also enables using IO operations to read from or write to *stringstreams, using strings instead of files.
ios
/ \
istream ostream
/----/ / \ / \ \----\
istringstream ifstream iostream ofstream ostringstream
/ \
fstream stringstream
Using File Streams
Open mode flags for files are in the same sprit as C:
ios::appis append to end, C's"a"ios::inis read, C's"r"ios::outis write, C's"w"ios::binaryis binary mode, C's"b"
Flags can be combined (via logical or, |, not via the strings "bw+" of C). Example:
#include <iostream>
#include <fstream> // file stream library
int main(void) {
// open for read only
// ios::in optional here, class ifstream makes it implicit
std::ifstream ifile("files.txt", std::ios::in);
// open for write, append to end
// ios::out optional here, ofstream makes it implicit
std::ofstream ofile("out.txt", std::ios::out | std::ios::app);
char ch;
int num;
do {
ifile.get(ch);
ifile >> num; // same I/O << and >> syntax as for std::cin/cout/cerr
ofile << ch << " " << num;
} while (!ifile.eof());
ifile.close();
ofile.close();
return 0;
}
Random access (block I/O) files are treated the same as in C. Member functions, manipulators & operators for iostreams (see below) can be used with iofstreams for sequential files also, not random access files.
stringstream
This is a string buffer that contains a sequence of characters, similar to a file stream.
- str() function can be used to get the content of the buffer
- str(string) sets the content of the buffer to the string argument
- << and >> operators can be used with stringstream to insert/extract content
- use member function .str() to get the string out of the object
- Versions specifically for input or output may also be used:
istringstream, ostringstream
#include <string>
#include <iostream>
#include <sstream>
int main() {
std::stringstream ss;
ss << "Hello" << ' ' << 35 << " world";
std::string word1, word2;
int num;
ss >> word1 >> num >> word2;
std::cout << word1 << ", " << word2 << '!' << std::endl;
std::cerr << ss.str() << std::endl;
return 0;
}
Formatted output in C++
Several methods for adding formatting to I/O
#include <iostream>
#include <iomanip> // I/O manipulators library
using std::cin; using std::cout;
using std::setw; using std::endl;
using std::setfill; using std::setprecision;
using std::fixed; using std::showpoint;
int main()
{
// inline manipulators examples from iomanip library
// setw(#) to set field width
cout << setw(8) << 100/29 << endl; // right justify in 8 char field
cout << setw(6) << "jo" << endl; // right justify in 6 field width
// setfill to change fill character
setfill('*');
cout << setfill('*') << setw(5) << "jo" << endl; // fill with * not ' '
// setfill is persistent, remains until reset or changed
cout << setfill(' ') ; // sets fill back to space
// setprecision/fixed/showpoint to change numerical formatting
cout << setprecision(3) << 100/29 << endl; // <=3 digits after decimal
cout << fixed; // forces fixed precision # of digits
cout << showpoint; // force decimal when precision=0
cout << 10.2344 << endl;
// alternative to above: use I/O member function flags
// flags determine how output is displayed
// changes are persistent
cout.setf(std::ios::fixed); // set fixed flag
cout.setf(std::ios::showpoint);
cout.precision(3); // 3 digits after decimal point
cout << 12.3 << endl;
cout.unsetf(std::ios::fixed);
// to save fill flag before changing and restore:
char oldfill = cout.fill('*');
cout << setw(4) << "jo" << endl; // **jo
cout.fill(oldfill);
cout << setw(4) << "jo" << endl; // jo
}
[See also operator overloading notes (to be added).]