There are many situations in which iostreams are useful:
File I/O. Iostreams can still be used for input and output to files, although file I/O has lost some of it former importance. In the past, alpha-numeric user interfaces were often built using file input/output to the standard input and output channels. Today almost all applications have graphical user interfaces.
Nevertheless, iostreams are still useful for input and output to files other than the standard input and output channels, and to all other kinds of external media that fit into the file abstraction. For example, you could use iostreams for input and output to communication streams such as sockets and pipes.
In-Memory I/O. Iostreams can perform in-memory formatting and parsing. Even with a graphical user interface, you must format the text you want to display. The standard iostreams offer internationalized in-memory I/O, which is a great help for text processing tasks like formatting. The formatting of numeric values, for example, depends on cultural conventions. The formatting layer uses a locale's numeric facets to adapt its formatting and parsing to cultural conventions.
Internationalized Text Processing. This function is actively supported by iostreams. Iostreams use locales. As locales are extensible, any kind of facet can be carried by a locale, and thus used by a stream. By default, iostreams use only the numeric and the code conversion facets of a locale. However, date, time, and monetary facets are available in the C++ Standard Library. Other cultural dependencies can be encapsulated in unique facets and made accessible to a stream. You can easily internationalize your use of iostreams to meet your needs.
Binary I/O. The traditional iostreams suffer from a number of limitations. The biggest is the lack of conversion abilities: if you insert a double into a stream, for example, you do not know what format will be used to represent this double on the external device. There is no portable way to insert it as binary.
Standard iostreams are by far more flexible. The code conversion performed on transfer of internal data to external devices can be customized: the transport layer delegates the task of converting to a code conversion facet. To provide a stream with a suitable code conversion facet for binary output, you can insert a double into a file stream in a portable binary data exchange format. No such code conversion facets are provided by the C++ Standard Library, however, and implementing such a facet is not trivial. As an alternative, you might consider implementing an entire stream buffer layer that can handle binary I/O.
Extending Iostreams. In a way, you can think of iostreams as a framework that can be extended and customized. You can add input and output operators for user-defined types, or create your own formatting elements, the manipulators. You can specialize entire streams, usually in conjunction with specialized stream buffers. You can provide different locales to represent different cultural conventions, or to contain special purpose facets. You can instantiate iostreams classes for new character types, other than char or wchar_t.