Recall that with printf, the original types of the arguments are lost, and so the format string must do double duty, encoding not only how to format each data value, but also the type of each data value. When we use iostreams, this disadvantage goes away. Formatting with iostreams looks like this:
int tuners = 225; const char *where = "Chicago"; std::cout << "There are " << tuners << " piano tuners in " << where << "\n";
Here, std::cout is a global variable of type ostream, corresponding to stdout or POSIX file descriptor 1. There's also std::cerr, corresponding to unbuffered stderr or POSIX file descriptor 2; std::clog, again corresponding to file descriptor 2 but fully buffered this time; and std::cin, a global ...