Chapter 16 - Notes

STL String Class

The std::string class is a container class that aids in string operations and manipulations:

  • It dynamically resizes itself

  • It supplies useful helper functions and methods that help manipulate the string

Motivation

A 'string' conceptually is simply an array of characters:

char name[20];

where name is a declaration of a character array of 20 elements (20 letters).

Problem:

  • This array can only hold a string of 20 characters or less

  • Resizing this statically allocated array is not possible

The solution could be to use a dynamically allocated array instead:

char dynamic_name = new char[length];

This is a dynamically allocated character array, instantiated with size length whose value can be deferred to at runtime.

Problem:

  • If you want to change the length of this array, you would first have to create a new dynamic array with the new length, copy the values from the old array, and then deallocate the old array.

  • This becomes very complicated when character arrays are used as member variables of an object, since the programmer has to define copy constructors and copy assignment operators to ensure deep copies of these string member variables.

The std::string class solves all these problems for us:

  • Reduces the effort of string creation and manipulation

  • Manages memory allocation details internally

  • Already implemented copy constructors and copy assignment operators that ensure member variables of type std::string are correctly copied.

  • Supplies useful utility functions that help truncating, finding, and erasing substrings.

  • Provides operators to help comparing strings.

Overall this allows us to focus on our application's requirements instead of mulling over string manipulation details.

Common Operations

The common string operations used are:

  • Copying

    • Creating a copy of another string object

  • Concatenating

    • Joining or combining two strings end-to-end

  • Finding

    • Looking for a substring or character within a string

  • Truncating

    • Slicing a string to extract a subsequence of characters

  • Reversing

    • Reversing the contents of a string

  • Case conventions

    • Turning an entire string uppercase, or lowercase

Creating a String

  • From a C-style string

const char* cstyleString = "Hello World!";

std::string myStr(cstyleString); 
std::string myStr2 = cstyleString; 
std::string myStr3("Hello World!");
std::string myStr4 = "Hello World!";
  • From another std::string

std::string myStr1("Hello World");
std::string myStrCopy(myStr1);
  • First n characters from another string

std::string myStr("Hello World");
std::string myPartialStr(myStr, 5);  // Only contains "Hello"
  • Repeat a character n times:

std::string myStrRepeat(10, 'a'); 
// Contains "aaaaaaaaaa"

Accessing the Internals

Indexing

The std::string class can be indexed into with the subscript operator ([]), much like a regular character array, to obtain the character at a particular index.

std::string myStr("Hello World");
std::cout << myStr[6] << std::endl;  // 'W'

Iterators

The std::string class also supports iterators like the STL containers.

std::string myStr("Hello World");
for (auto it = myStr.begin(); it != myStr.end(); it++) {
    std::cout << *it << std::endl;
}

Character Contents

Under the hood, the std::string class simply stores the string contents within a dynamic character array, which can be obtained with the .c_str() member function.

This returns a pointer to the first character in the character array.

std::string myStr("Hello World");
const char* myStrAsCStr = myStr.c_str();

std::cout << myStrAs

String Concatenation

String concatenation can be achieved by using the += operator or the .append() member function.

std::string str1("Hello");
std::string str2(" World!");

str1 += str2;  // str1: "Hello World!"
str1.append(str2);  // str1: "Hello World! World!"

Finding a Character or Substring

The .find() member function can find a character or a substring in a given std::string object:

std::string str1("Hello World!");

// Find "Wor" in "Hello World", starting at position 0
size_t position = str1.find("Wor", 0); 

// Check if the substring was found, compare against string::npos
if (position != string::npos) {
    std::cout << "'Wor' was found at position: " << position << std::endl;
} else {
    std::cout << "'Wor' was not found" << std::endl;
}

The other member function functions such as .find_first_of(), .find_first_not_of(), find_last_of(), and find_last_not_of() work in similar ways.

Truncating Strings

Erasing a number of characters starting at a given position

std::string sampleStr ("Hello String! Wake up to a beautiful day!");
// Remove 28 characters starting at position 13
sampleStr.erase (13, 28); // Hello String!

Erasing a character given an iterator

std::string str1("Hello World!");
str1.erase(str1.begin() + 6); // Removes 'W'

Erasing characters between a range

std::string str1("Hello World!");
str1.erase(str1.begin(), str1.begin()+6);  // "World!"

Slicing Strings

The .subtr() member function is used to obtain a substring from another string.

string substr (size_t pos = 0, size_t len = npos) const;
  • pos: Position of the first character to be copied as a substring.

  • len: Number of characters to include in the substring

#include <iostream>
#include <string>

int main ()
{
  std::string str="We think in generalities, but we live in details.";
                                           // (quoting Alfred N. Whitehead)

  std::string str2 = str.substr (3,5);     // "think"

  std::size_t pos = str.find("live");      // position of "live" in str

  std::string str3 = str.substr (pos);     // get from "live" to the end

  std::cout << str2 << ' ' << str3 << '\n';
}

Reversing Strings

Strings can be reversed using the std::reverse template function from the <algorithm> library:

std::string sampleStr("Hello String! We will reverse you!");
reverse(sampleStr.begin(), sampleStr.end());

String Case Conventions

Strings can be converted between uppercase and lowercase using the std::transform function with toupper() and tolower():

#include <iostream>
#include <algorithm>
#include <string>

int main ()
{
    std::cout << "Please enter a string for case-convertion:" << std::endl;
    std::cout << "> ";
    
    // Get a string from the user
    std::string inStr;
    getline (std::cin, inStr);
    std::cout << std::endl;
    
    // Convert to uppercase 
    std::transform(inStr.begin(), inStr.end(), inStr.begin(), toupper);
    std::cout << "The string converted to upper case is: " << std::endl;
    std::cout << inStr << std::endl << std::endl;
    
    // Convert to lowercase
    transform(inStr.begin(), inStr.end(), inStr.begin(), tolower);
    std::cout << "The string converted to lower case is: " << std::endl;
    std::cout << inStr << std::endl << std::endl;
}

Last updated

Was this helpful?