C/C++ Arena

Step 3 of 7

std::string_view

A function that only reads a string often takes const std::string&. That works, but when a caller passes a literal like "hello", a temporary std::string must be built first, copying the characters (and allocating heap memory if the text is long). And taking a piece of a string with substr makes yet another copy.

std::string_view (from <string_view>) is a lightweight view: just a pointer to some characters and a length. It never owns or copies the text. It accepts literals, std::strings and parts of either for free.

#include <iostream>
#include <string>
#include <string_view>

std::string_view file_extension(std::string_view path) {
    auto dot = path.rfind('.');
    if (dot == std::string_view::npos) return {};   // empty view
    return path.substr(dot + 1);                    // a view into path: no copy
}

int count_char(std::string_view s, char c) {
    int n = 0;
    for (char x : s) n += (x == c);
    return n;
}

int main() {
    std::cout << file_extension("report.final.pdf") << "\n";
    std::string name = "photo.jpeg";
    std::cout << file_extension(name) << "\n";
    std::cout << "[" << file_extension("README") << "]\n";

    std::string_view v = "  banana  ";
    v.remove_prefix(2);                             // just moves the start
    std::cout << count_char(v, 'a') << " " << v.size() << " " << v.starts_with("ban") << "\n";
}
pdf
jpeg
[]
3 8 1

How it works

The danger: views don't keep text alive

A view points at characters owned by someone else. If the owner dies, the view dangles:

std::string_view bad() {
    std::string s = "temporary";
    return s;          // s is destroyed here; the view points at freed memory
}

Rule of thumb: use string_view for parameters; return it only when it points into something the caller owns, like file_extension does.

Your task: trim

Move the start past leading spaces with remove_prefix(1) while the first character is ' ', then do the same at the end with remove_suffix(1) and back(). Check empty() first each time so an all-spaces string ends up as an empty view.

Your turn: write std::string_view trim(std::string_view s) that returns the view without leading and trailing spaces.

Previous: std::variant and std::visit Next: Concepts