Chapter 3. String, Vectors, and Arrays

3.1 Namespace using Declarations

These names use the scope operator (::), which says that compiler should look in the scope of the left-hand operand for the name of the right-hand operand.

Code inside headers ordinarily should not use using declarations. If a header has a using declaration, then every program that includes that header gets that same using declaration.

3.2 Library string Type

A string is a variable-length sequence of characters. To use the string type, it must include the string header.

3.2.1 Defining and Initialising strings

string s1;                // Default initialisation; s1 is the empty string
string s2(s1);            // s2 is a copy of s1
string s2 = s1;           // Equivalent to s2(s1), s2 is a copy of s1
string s3("value");       // s3 is a copy of the string literal, not including the null
string s3 = "value";      // Equivalent to s3("value"), s3 is a copy of the string literal
string s4(n, 'c');        // Initialise s4 with n copies of the character 'c'

3.2.2 Operations on strings

string Operations

description

os << s

Write s onto output stream os. Returns os.

is >> s

Reads whitespace-separated string from is into s. Returns is.

getline(is, s)

Reads a line of input from is into s. Returns is.

s.empty()

Returns true if s is empty; otherwise returns false.

s.size()

Returns the number of characters in s.

s[n]

Returns a reference to the char at position n in s; position start at 0.

s1 + s2

Returns a string that is the concatenation of s1 and s2.

s1 = s2

Replaces characters in s1 with a copy of s2.

s1 == s2

The strings s1 and s2 are equal if they contain the same characters.

s1 != s2

Equality is case-sensitive.

<, <=, >, >=

Comparisons are case-sensitive and use dictionary ordering.

Reading an unknown number of strings

while(cin >> word) { ... } // read until end-of-file
while (getline(cin, word)) { ... } // read input a line a time until end-of-file

Comparing strings

  1. If two strings have different lengths and if every character in the shorter string is equal to the corresponding character of the longer string, then the shorter string is less than the longer one.

  2. If any characters at corresponding position in the two strings differ, then the result of the string comparison is the result of comparing the first character at which the strings differ.

Adding strings and Literals

string s1 = "hello, ", s2 = "world\n";
string s3 = s1 + s2;    // s3 is hello, world\n
s1 += s2; // equivalent to s1 = s1 + s2
string s4 = "hello", s5 = "world";
string s6 = s4 + ", " + s5 + "\n";

3.2.3 Dealing with the Characters in a string

The range-base for statement iterates through the elements in a given sequence and performs some operation on each value in that sequence.

for (declaration : expression)
    statement

cctype Function

Description

isalnum(c)

true if c is a letter or a digit.

isalpha(c)

true if c is a letter.

iscntrl(c)

true if c is a control character.

isdigit(c)

true if c is a digit.

isgraph(c)

true if c is not a space but is printable.

islower(c)

true if c is a lowercase letter.

isprint(c)

true if c is a printable character.

ispunct(c)

true if c is a punctuation character.

isspace(c)

true if c is whitespace.

isupper(c)

true if c is uppercase letter.

isxdigit(c)

true if c is a hexadecimal digit.

tolower(c)

if c is an uppercase letter, returns its lowercase equivalent; otherwise return c unchanged.

toupper(c)

if c is a lowercase letter, returns its uppercase equivalent; otherwise returns c unchanged.

3.3 Library vector Type

A vector is a collection of objects, all of which have the same type.

#include <vector>
using std::vecotr;
vector<int> ivec;
vector<vector<string>> file;

vector is a template, not a type. Types generated from vector must include the element type.

3.3.1 Defining and Initialising vectors

vector<T> v1;                    // Defualt initialisation; v1 is empty.
vector<T> v2(v1);                // v2 has a copy of each element in v1.
vector<T> v2 = v1;               // Equivalent to v2(v1), v2 is a copy of the elements in v1.
vector<T> v3(n, val);            // v3 has n elements with value val.
vector<T> v4(n);                 // v4 has n copies of a value-initialised object.
vector<T> v5{a, b, c...};        // v5 has as many elements as there are initialisers; elements are initialised by corresponding initialisers.
vector<T> v5 = {a, b, c...};     // Equivalent to v5{a, b, c...}.

3.3.2 vector Operations

vector Operations

Description

v.empty()

Returns true if v is empty; otherwise return false.

v.size()

Returns the number of elements in v.

v.push_back(t)

Adds an element with value t to end of v.

v[n]

Returns a reference to the element at position n in v.

v1 = v2

Replaces the element in v1 with a copy of the elements in v2.

v1 = {a, b, c...}

Replaces the elements in v1 with a copy of the elements in the comma-separated list.

==, !=

v1 and v2 are equal if they have the same number of elements and each element in v1 is equal to the corresponding element in v2.

<, <=, >, >=

Have their normal meanings using dictionary ordering.

3.4 Introducing Iterators

The iterator provides a method to indirect access to an object.

3.4.1 Using Iterators

The iterator returned by end is often referred to as the off-the-end iterator or abbreviated as "the end iterator".

iterator Operations

Description

*iter

Returns a reference to the element denoted by the iterator iter.

iter->mem

Dereferences iter and fetches the member named mem from the underlying element. Equivalent to (*iter).mem.

++iter

Increments iter to refer to the next element in the container.

--iter

Decrements iter to refer the previous element in the container.

==, !=

Compare two iterator for equality. Two iterators are equal if they denote the same element or if they are the off-the-end iterator for the same container.

iter + n

Adding an integral value n to an iterator yields an iterator that many elements forward within the container.

iter - n

Subtracting an integral value n from an iterator yields an iterator that many elements forward within the container.

iter += n

Compound-assignment for iterator addition.

iter -= n

Compound-assignment for iterator subtraction.

iter1 - iter2

Subtracting two iterators yields the number that when added to the right-hand iterator yields the left-hand iterator. The iterators must denote elements in the same container.

>, >=, <, <=

One iterator is less than another if it refers to an element that appears in the container before the one referred to by the other iterator.

3.5 Arrays

3.5.1 Defining and Initialising Built-in Arrays

Arrays are a compound type. An array declarator has the form a[d], where a is the name being defined and d is the dimension of the array. The dimension specifies the number of elements and must be greater than zero. The dimension must be known at compile time, which means that the dimension must be a constant expression.

If we omit the dimension, the compiler infers it from the number of initialiser. If we specify a dimension, the number of initialisers must not exceed the specified size.

int a2[] = {0, 1, 2};
int a3[5] = {0, 1, 2};    // equivalent to a3[] = {0, 1, 2, 0, 0}

Character arrays have an additional form of initialisation, arrays from a string literal.

char a1[] = {'C', '+', '+'};        // list initialisation, no null
char a2[] = {'C', '+', '+', '\0'};  // list initialisation, explicit null
char a3[] = "C++";                  // null terminator added automatically
const char a4[6] = "Daniel";        // error: no space for the null

The arrays cannot be initialised and assigned via copying another array.

Understanding Complicated Array Declarations

int *ptrs[10];                // ptrs is an array of ten pointers to int
int &refs[10];                // error: no arrays of references
int (*Parray)[10] = &arr;     // Parray points to an array of ten ints
int (&arrRef)[10] = arr;      // arrRef refers to an array of ten ints
int *(&arry)[10] = ptrs;      // arry is a reference to an array of ten pointers

3.5.2 Accessing the Elements of an Array

for (auto i : arrays)
    statement

3.5.3 Pointers and Arrays

string nums[] = {"one", "two", "three"};    // array of strings
string *p = &nums[0];                       // p points to the first element in nums
string *p2 = nums;                          // equivalent to p2 = &nums[0]
int ia[] = {0, 1, 2};                       // ia is an array of three ints
auto ia2(ia);                               // ia2 is an int* that points to the first element in ia
decltype(ia) ia3 = {0, 1, 2};               // ia3 is an array of three ints

To make it easier and safer to pointers, the new library includes two functions, named begin and end.

int ia[] = {0, 1, 2, 3};
int *beg = begin(ia);
int *last = end(ia);

Pointer Arithmetic

It can use the relational operators to compare pointers that point to elements of an array, or one past element in that array.

int *b = arr, *e = arr + sz;
while (b < e) {
    // use b
}

int i = 0, sz = 42;
int *p = &i, *e = &sz;
while (p < e) { ... }    // undefined: p and e are unrelated

Subscripts and Pointers

int *p = ia;        // pointers to the first element in ia
int i = *(p + 2);   // equialent to i = ia[2]

int *p = &ia[2];    // p points to the element indexed by 2
int j = p[1];       // p[1] is the same element as ia[3]
int k = p[-2];      // p[-2] is the same element as ia[0]

3.5.4 C-Style Character Strings

Character string literals are an instance of a more general construct that C++ inherits from C: C-style character strings. Strings that follow this convention are stored in character arrays and are null terminated.

The Standard C library provides a set of functions, that operate on C-style strings. These function are defined in the cstring header, which is the C++ version of the C header string.h.

C-Style Character String Functions

Description

strlen(p)

Return the length of p, not counting the null.

strcmp(p1, p2)

Compares p1 and p2 for equality. Returns 0 if p1 == p2, a positive value if p1 > p2, a negative value if p1 < p2.

strcat(p1, p2)

Appends p2 to p1. Returns p1.

strcpy(p1, p2)

Copies p2 into p1. Returns p1.

3.5.3 Interfacing to Older Code

The name c_str indicated that the function returns a C-style character string. The 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 vector can be used an array to initialise.

int init_arr[] = {0, 1, 2, 3};
vector<int> ivec(begin(init_arr), end(init_arr));

3.6 Multidimensional Arrays

Strictly speaking, there are no multidimensional arrays in C++. What are commonly referred to as multidimensional arrays are actually arrays of arrays.

int ia[3][4];    // array of size 3; each element is an array of ints of size 4
int ia[3][4] = {    // three elements; each elementis an array of size 4
    {0, 1, 2, 3},    // initialsers for rwo indexed by 0
    {4, 5, 6, 7},    // initialsers for rwo indexed by 1
    {8, 9, 10, 11}    // initialsers for rwo indexed by 2
};
// equivalent initialisation without the optional nested braces for each row
int ia[3][4] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};

// using a Range for with Multidimensional arrays
for (auto row : ia)
    for (auto col : row)
        ...

int *ip[4];    // array of pointers to int
int (*ip)[4];    // pointers to an array of four ints

// Type Aliases
using int_array = int[4];
typedef int int_array[4];

Last updated

Was this helpful?