Strings
reading
Cyganek section 3.6
std::string on cplusplus.com
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.
When working with strings, we include the <string>
header.
Note
In C++, single characters (char
) are enclosed in single-quotes, e.g., 'A'
,
while strings are enclosed in double quotes, e.g. "string"
.
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.
Here’s a first example. We’ll create a string and we’ll concatenate
another string onto it using the +
operator:
#include <iostream>
#include <string>
int main() {
std::string example{"This is PHY 504"};
std::cout << "original string: " << std::endl;
std::cout << std::endl;
example += ":\n Computational Methods in Physics and Astrophysics I\n";
example += "Spring 2022";
std::cout << example << std::endl;
}
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.
Note
We used an escape sequence here, \n
,
to create a newline. \n
is slightly different than
std::endl
—the latter also flushes the output buffer.
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, '-');
Here, '-'
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
has find and replace member functions. Here’s an example of
extracting the basename of a file from a path and then replacing the
extension.
There are a lot of different ways we can do a replace: std::string::replace calls .
#include <iostream>
#include <string>
int main() {
std::string filename{"~/classes/test.cpp"};
std::cout << "filename: " << filename << std::endl;
// 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 length, 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;
}
Tip
C++17 introduced the filesystem
library that includes a stem
function
that can do this as well. We’ll look at the filesystem library
later.
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/