Strings

reading

Cyganek section 3.6

A C++ std::string has many similarities to a vector (in particular, you could imagine doing std::vector<char>. But it is specific to strings, and as such, has many useful functions that operate on strings.

Warning

C++ can also use older C-style strings, which are essentially a null-terminated array of characters, e.g.,

char c_string[] = "this is my string";

These are quite inflexible and can lead to coding errors if you are not careful, and we will avoid them as much as possible.

Note

In C++, single characters (char) are enclosed in single-quotes, e.g., 'A', while strings are enclosed in double quotes, e.g. "string".

When working with strings, we include the <string> header.

Here’s a first example. We’ll create a string and we’ll concatenate another string onto it using the + operator:

Listing 9 string_example.cpp
#include <iostream>
#include <string>

int main() {

    std::string example{"This is PHY 504"};

    example += ":\n Computational Methods in Physics and Astrophysics I\n";
    example += "Spring 2022";

    std::cout << example << std::endl;
}

Note that in this example, the strings that we add to our initial string are actually C-style strings, but std::string knows how to work with them.

Just like with vectors, we can use a constructor to create an initial string filled with a character repeated many times. For instance, here’s an 80-character line:

std::string line(80, '-');

Note that '-' is a char and not a string.

Note

A nice overview of working with C++ strings is provided by “hacking C++”: std::string

Find and Replace

string s have find and replace methods. Here’s an example of extracting the basename of a file from a path and then replacing the extension.

Note: there are a lot of different ways we can do a replace: std::string::replace calls .

Listing 10 string_replace.cpp
#include <iostream>
#include <string>

int main() {

    std::string filename{"~/classes/test.cpp"};

    // let's find just the base file name -- reverse find for '/'

    auto ipos = filename.rfind('/');

    // create a substring containing just the base name
    // if we don't provide a lenght, substr goes to the end

    std::string basename = filename.substr(ipos+1);

    std::cout << "basename = " << basename << std::endl;

    // now let's change the extension from .cpp to .txt

    auto ipos_ext = basename.rfind('.');

    // there are many forms of replace -- here's well use iterators that mark
    // the start and end of the original string and those of the string we want
    // to substitute
    
    std::string new_ext = ".txt";

    basename.replace(basename.begin()+ipos_ext, basename.end(),
                     new_ext.begin(), new_ext.end());

    std::cout << "basename = " << basename << std::endl;

}

Other Functions

There are a large number of member functions that work on strings. See for instance: https://www.cplusplus.com/reference/string/string/

try it…

Let’s try to use std::string::find_first_of, following this: https://www.cplusplus.com/reference/string/string/find_first_of/