Text processing is everywhere, and choosing between string, string_view and C strings affects both safety and speed.
std::string (header <string>) owns a mutable sequence of chars and manages its own memory. It behaves like a value: copying a string copies its characters, and == compares contents.
The common operations:
- Concatenate with
+and+=;size()andempty(); index withs[i]. s.substr(pos, count)copies out a piece;s.find("x")returns a position orstd::string::nposif not found.- C++20 adds
starts_withandends_with; C++23 addscontains. - Convert with
std::to_string(42)andstd::stoi("42")/std::stod(these throw on bad input).
A string literal like "abc" is not a std::string; it's a const char[4] array inherited from C, with a hidden terminating '\0'. So "a" + "b" doesn't compile (it tries to add two pointers), while std::string{"a"} + "b" works. Short strings (typically up to 15 characters) are stored inside the string object itself, the small string optimization, so they don't allocate.
std::string_view (C++17, header <string_view>) is a non-owning view: just a pointer and a length. It can refer to a std::string, a literal or part of a buffer without copying, which makes std::string_view the best parameter type for functions that only read text. Its substr is free.
The flip side: a view does not keep the text alive. Never return a string_view into a local string, and never store one that outlives the string it points to.
char holds bytes, not Unicode characters; UTF-8 text works fine in a std::string, but size() counts bytes.
Example
#include <cctype>
#include <iostream>
#include <string>
#include <string_view>
bool is_header(std::string_view line) { // cheap read-only view of any text
return line.starts_with("#"); // C++20
}
int main() {
std::string name = "Ada";
std::string greeting = "Hello, " + name + "!"; // needs one std::string operand
greeting += " Welcome.";
std::cout << greeting.size() << '\n'; // 20
std::cout << greeting.substr(7, 3) << '\n'; // Ada (pos, count)
auto pos = greeting.find("Welcome");
if (pos != std::string::npos) std::cout << "found at " << pos << '\n'; // 12
int n = std::stoi("42"); // string -> int
std::string s = std::to_string(n * 2); // int -> string "84"
std::cout << s << ' ' << (name == "Ada") << ' ' << is_header("# title") << '\n'; // 84 1 1
for (char& c : name) c = static_cast<char>(std::toupper(static_cast<unsigned char>(c)));
std::cout << name << '\n'; // ADA
}Remember
std::stringowns its text;std::string_viewonly looks at someone else's- Take read-only text parameters as
std::string_view findreturnsstd::string::nposwhen nothing matches
Watch out for
- Returning a
std::string_viewthat points into a local or temporarystd::string.