The first chapter in this section introduces the Standard C++ stringclass, which is a powerful tool that simplifies most of the text-processing chores you might have. The stringclass might be the most thorough string manipulation tool you’ve ever seen. Chances are, anything you’ve done to character strings with lines of code in C can be done with a member function call in the string class .
Chapter 4 covers the iostreamslibrary, which contains classes for processing input and output with files, string targets, and the system console .
Although Chapter 5, "Templates in Depth," is not explicitly a library chapter, it is necessary preparation for the two that follow. In Chapter 6 we examine the generic algorithms offered by the Standard C++ library. Because they are implemented with templates, these algorithms can be applied to any sequence of objects. Chapter 7 covers the standard containers and their associated iterators. We cover algorithms first because they can be fully explored by using only arrays and the vector container (which we have been using since early in Volume 1). It is also natural to use the standard algorithms in connection with containers, so it’s a good idea to be familiar with the algorithm before studying the containers.
[ ]
One of the biggest time-wasters in C is using character arrays for string processing: keeping track of the difference between static quoted strings and arrays created on the stack and the heap, and the fact that sometimes you’re passing around a char*and sometimes you must copy the whole array.
Especially because string manipulation is so common, character arrays are a great source of misunderstandings and bugs. Despite this, creating string classes remained a common exercise for beginning C++ programmers for many years. The Standard C++ library stringclass solves the problem of character array manipulation once and for all, keeping track of memory even during assignments and copy-constructions. You simply don’t need to think about it .
This chapter examines the Standard C++ stringclass, beginning with a look at what constitutes a C++ string and how the C++ version differs from a traditional C character array. You’ll learn about operations and manipulations using stringobjects, and you’ll see how C++ strings accommodate variation in character sets and string data conversion. [28] Some of the material in this chapter was originally created by Nancy Nicolaisen.
Handling text is perhaps one of the oldest of all programming applications, so it’s not surprising that the C++ stringdraws heavily on the ideas and terminology that have long been used for this purpose in C and other languages. As you begin to acquaint yourself with C++ strings, this fact should be reassuring. No matter which programming idiom you choose, there are really only about three things you want to do with a string:
· Create or modify the sequence of characters stored in the string.
· Detect the presence or absence of elements within the string.
· Translate between various schemes for representing stringcharacters .
You’ll see how each of these jobs is accomplished using C++ stringobjects .
In C, a string is simply an array of characters that always includes a binary zero (often called the null terminator ) as its final array element. There are significant differences between C++ strings and their C progenitors. First, and most important, C++ strings hide the physical representation of the sequence of characters they contain. You don’t have to be concerned at all about array dimensions or null terminators. A stringalso contains certain "housekeeping" information about the size and storage location of its data. Specifically, a C++ stringobject knows its starting location in memory, its content, its length in characters, and the length in characters to which it can grow before the stringobject must resize its internal data buffer. C++ strings therefore greatly reduce the likelihood of making three of the most common and destructive C programming errors: overwriting array bounds, trying to access arrays through uninitialized or incorrectly valued pointers, and leaving pointers "dangling" after an array ceases to occupy the storage that was once allocated to it .
The exact implementation of memory layout for the string class is not defined by the C++ Standard. This architecture is intended to be flexible enough to allow differing implementations by compiler vendors, yet guarantee predictable behavior for users. In particular, the exact conditions under which storage is allocated to hold data for a string object are not defined. String allocation rules were formulated to allow but not require a reference-counted implementation, but whether or not the implementation uses reference counting, the semantics must be the same. To put this a bit differently, in C, every chararray occupies a unique physical region of memory. In C++, individual stringobjects may or may not occupy unique physical regions of memory, but if reference counting is used to avoid storing duplicate copies of data, the individual objects must look and act as though they do exclusively own unique regions of storage. For example: .
//: C03:StringStorage.cpp
//{L} ../TestSuite/Test
#include
#include
#include "../TestSuite/Test.h"
using namespace std;
class StringStorageTest : public TestSuite::Test {
public:
void run() {
string s1("12345");
// This may copy the first to the second or
// use reference counting to simulate a copy
string s2 = s1;
test_(s1 == s2);
// Either way, this statement must ONLY modify s1
s1[0] = '6';
cout << "s1 = " << s1 << endl;
cout << "s2 = " << s2 << endl;
test_(s1 != s2);
}
};
int main() {
StringStorageTest t;
t.run();
return t.report();
} ///:~
An implementation that only makes unique copies when a string is modified is said to use a copy-on-write strategy. This approach saves time and space when strings are used only as value parameters or in other read-only situations.
Whether a library implementation uses reference counting or not should be transparent to users of the stringclass. Unfortunately, this is not always the case. In multithreaded programs, it is practically impossible to use a reference-counting implementation safely. [29] It’s difficult to make reference-counting implementations thread safe. (See Herb Sutter, More Exceptional C++ , pp. 104вЂ"14). See Chapter 10 for more on programming with multiple threads.
Creating and initializing C++ strings
Creating and initializing strings is a straightforward proposition and fairly flexible. In the SmallString.cppexample in this section, the first string, imBlank, is declared but contains no initial value. Unlike a C chararray, which would contain a random and meaningless bit pattern until initialization, imBlankdoes contain meaningful information. This stringobject is initialized to hold "no characters" and can properly report its zero length and absence of data elements through the use of class member functions.
The next string, heyMom, is initialized by the literal argument "Where are my socks?" This form of initialization uses a quoted character array as a parameter to the stringconstructor. By contrast, standardReplyis simply initialized with an assignment. The last string of the group, useThisOneAgain, is initialized using an existing C++ stringobject. Put another way, this example illustrates that stringobjects let you do the following: .
Читать дальше