Input/Output
As with C, Input/Output is not part of the language, but support
is provided by a library. Most programs need to
use #include <iostream>
. You may also need
#include <fstream>
for file I/O,
#include <iomanip>
for greater control over formatting,
and #include <sstream>
for I/O to and from
strings.
Simple I/O
The following illustrates the use of putback() for an input stream. istreams also have an ignore function (is.ignore(5) would ignore the next 5 characters) and a peek() function which looks at the next character without removing it from the stream.
istream& eatwhite(istream& is) { char c; while(is.get(c)) { if (!isspace(c)) { is.putback(c); break; } return is; } }
The following illustrates the use of I/O to and from files. Given the name of 2 files on the command line (which are available to main as C-style character arrays), it does a file copy.
void error(string p, string p2="") { cerr<<p << ' ' << p2 << endl; std::exit(1); } int main (int argc, char* argv[]) { if (argc != 3) error("wrong number of arguments"); std::ifstream from(argv[1]); if (!from) error("cannot open input file", string(argv[1])); std::ofstream to(argv[2]); if (!to) error("cannot open output file", string(argv[2])); char ch; while (from.get(ch)) to.put(ch); if (!from || !to) error("something strange happened"); }
You can force the screen/file output to be up-to-date by using
cout.flush() or cout << flush;
but this isn't usually necessary.
If you want to write or read raw (binary) data (rather than strings that represent numbers) you can use write, read and casts (section 13) to keep the compiler happy. The following program writes 100 random integers into a file then reads them back.
[fontsize=\small,frame=single,formatcom=\color{progcolor}] #include <iostream> #include <fstream> #include <cstdlib> // to use rand using namespace std; int main() { ofstream outfile("myresults",ios::out|ios::binary); if (outfile.good() == false) { cerr << "Cannot write to 'myresults'" << endl; exit(1); } int num; for (int i=0; i<100; i++){ num=rand(); outfile.write(reinterpret_cast<const char*>(&num), sizeof(num)); } outfile.close(); ifstream infile("myresults"); if (infile.good() == false) { cerr << "Cannot open 'myresults'" << endl; exit(1); } int count=0; while(infile.read(reinterpret_cast<char*>(&num), sizeof(num))) { cout << num << endl; count++; } cout << count << " numbers read in" << endl; infile.close(); return 0; }
Formatting
The way that text and numbers are output can be controlled.
#include <iostream> #include <iomanip> #include <cmath> using namespace std; int main() { int i=10; cout << "i = " << i << " (default)\n" ; cout << hex << "i = " << i << " (hex)\n"; double d = sqrt(7.0); cout << "d=sqrt(7.0)=" << d << endl; cout.precision(3); cout << "After cout.precision(3), d=" << d << endl; return 0; }
There many other routines too, amongst them
cout.setf(ios_base::oct,ios_base::basefield); // set base to 8 const ios_base::fmtflags myopt = ios_base::left|ios_base::oct; ios_base::fmtflags old_options = cout.flags(myopt); //set base to 8 // and alignment to left. cout.precision(8); // set precision to 8 cout.setf(ios_base::scientific, ios_base::floatfield); cout.width(4); // output at least four characters cout.fill('*'); // fill gaps with '*' cin.noskipws(); // don't skip white space
Stream Iterators
Iterators can be used on streams, providing an elegant way to integrate I/O with container classes. You've seen them already in the Standard Library section.
ostream_iterator<string> oo (cout); int main() *oo = "Hello"; ++oo; *oo = "World";
Output of User-Defined types
One way to do this is by overloading the stream insertion operator. The following defines how complex numbers should be printed out -
ostream& operator<<(ostream&s, complex z) // returns ostream& so can be chained { return s << '(' << z.real() << ',' << z.imag() << ')'; }
Input of User-Defined types
The following code reads in a complex number that's provided in the form (a,b) or (a)
istream& operator>>(istream&s, complex &a) // returns istream& so can be chained { double re=0, im=0; char c=0; s>>c; if (c== '(') { s>>re >> c; if (c == ',') s >> im >> c; if (c != ')') s.clear(ios_base::badbit); } else { s.putback(c); s>> re; } if (s) a = complex(re,im); return s; }
String streams
stringstreams are streams that are attached to a string
rather than a file and letting you use the same syntax as file I/O.
They are defined in <sstream>
.
[fontsize=\small,frame=single,formatcom=\color{progcolor}] #include <iostream> #include <string> #include <sstream> using namespace std; int main() { int i = 7; string s1 = "He is "; string s2 = " years old"; ostringstream ostring; ostring << s1 << i << s2; cout << "ostring =" << ostring.str() << endl; return 0; }