Many C++ programs predate the standard library and do not use the string
and vector
types. Moreover, many C++ programs interface to programs written in C or other languages that cannot use the C++ library. Hence, programs written in modern C++ may have to interface to code that uses arrays and/or C-style character strings. The C++ library offers facilities to make the interface easier to manage.
string
s and C-Style StringsIn § 3.2.1 (p. 84) we saw that we can initialize a string
from a string literal:
string s("Hello World"); // s holds Hello World
More generally, we can use a null-terminated character array anywhere that we can use a string literal:
• We can use a null-terminated character array to initialize or assign a string
.
• We can use a null-terminated character array as one operand (but not both operands) to the string
addition operator or as the right-hand operand in the string
compound assignment (+=
) operator.
The reverse functionality is not provided: There is no direct way to use a library string
when a C-style string is required. For example, there is no way to initialize a character pointer from a string
. There is, however, a string
member function named c_str
that we can often use to accomplish what we want:
char *str = s; // error: can't initialize a char* from a string
const char *str = s.c_str(); // ok
The name c_str
indicates that the function returns a C-style character string. That is, it returns a pointer to the beginning of a null-terminated character array that holds the same data as the characters in the string
. The type of the pointer is const char*
, which prevents us from changing the contents of the array.
The array returned by c_str
is not guaranteed to be valid indefinitely. Any subsequent use of s
that might change the value of s
can invalidate this array.
If a program needs continuing access to the contents of the array returned by str()
, the program must copy the array returned by c_str
.
vector
In § 3.5.1 (p. 114) we noted that we cannot initialize a built-in array from another array. Nor can we initialize an array from a vector
. However, we can use an array to initialize a vector
. To do so, we specify the address of the first element and one past the last element that we wish to copy:
int int_arr[] = {0, 1, 2, 3, 4, 5};
// ivec has six elements; each is a copy of the corresponding element in int_arr
vector<int> ivec(begin(int_arr), end(int_arr));
The two pointers used to construct ivec
mark the range of values to use to initialize the elements in ivec
. The second pointer points one past the last element to be copied. In this case, we used the library begin
and end
functions (§ 3.5.3, p. 118) to pass pointers to the first and one past the last elements in int_arr
. As a result, ivec
will have six elements each of which will have the same value as the corresponding element in int_arr
.
The specified range can be a subset of the array:
// copies three elements: int_arr[1], int_arr[2], int_arr[3]
vector<int> subVec(int_arr + 1, int_arr + 4);
This initialization creates subVec
with three elements. The values of these elements are copies of the values in int_arr[1]
through int_arr[3]
.