Professional C__ - Marc Gregoire [264]
regex reg("([\w]+)");
const string format("$1\n");
while (true) {
cout << "Enter a string to split over multiple lines (q=quit): ";
string str;
if (!getline(cin, str) || str == "q")
break;
cout << regex_replace(str, reg, format,
regex_constants::format_no_copy) << endl;
}
Code snippet from RegularExpressions\regex_replace_3.cpp
The output of this program can be as follows:
Enter a string to split over multiple lines (q=quit): This is a test.
This
is
a
test
SUMMARY
This chapter started with a discussion on the C++ string class and why you should use it instead of the old plain C-style character arrays. It also explained a number of new helper functions added to C++11 to make it easier to convert numerical values into strings and vice versa, and introduced the concept of raw string literals.
The second part of this chapter gave you an appreciation for coding with localization in mind. As anyone who has been through a localization effort will tell you, adding support for a new language or locale is infinitely easier if you have planned ahead, for example by using Unicode characters and being mindful of locales.
The last part of this chapter explained the new C++11 regular expressions library. Once you know the syntax of regular expressions, it becomes much easier to work with strings. Regular expressions allow you to easily validate strings, search for sub-strings inside a source string, perform find-and-replace operations on strings, and so on. It is highly recommended to get to know them and to start using them instead of writing your own string manipulation routines. They will make your life easier.
Chapter 15
Demystifying C++ I/O
WHAT’S IN THIS CHAPTER?
What streams are
How to use streams for input and output of data
What the available standard streams are in the Standard Library
A program’s fundamental job is to accept input and produce output. A program that produces no output of any sort would not be very useful. All languages provide some mechanism for I/O, either as a built-in part of the language or through an OS-specific API. A good I/O system is both flexible and easy to use. Flexible I/O systems support input and output through a variety of devices, such as files and the user console. They also support reading and writing of different types of data. I/O is error-prone because data coming from a user can be incorrect or the underlying file system or other data source can be inaccessible. Thus, a good I/O system is also capable of handling error conditions.
If you are familiar with the C language, you have undoubtedly used printf() and scanf(). As I/O mechanisms, printf() and scanf() are certainly flexible. Through escape codes and variable placeholders, they can be customized to read in specially formatted data, or output any value that the formatting codes permit, which is currently limited to integer/character values, floating point values, and strings. However, printf() and scanf() falter on other measures of good I/O systems. They do not handle errors particularly well, they are not flexible enough to handle custom data types, and, worst of all in an object-oriented language like C++, they are not at all object oriented!
C++ provides a more refined method of input and output through a mechanism known as streams. Streams are a flexible and object-oriented approach to I/O. In this chapter, you will learn how to use streams for data output and input. You will also learn how to use the stream mechanism to read from various sources and write to various destinations, such as the user console, files, and even strings. This chapter covers the most commonly used I/O features.
USING STREAMS
The stream metaphor takes a bit of getting used to. At first, streams may seem more complex than traditional C-style I/O, such as printf(). In reality, they seem complicated initially only because there is a deeper metaphor behind streams than there is behind printf().