std::filesy...::path::stem(3)
π std::filesystem::path::stem β the C++ Standard Library glow-up
okay so bestie, you clicked on std::filesy...::path::stem(3) from the C++ Standard Libary and honestly? iconic choice. this is the page that teaches you how to peel the extension off a filename and keep the good part. slay. π
β¨ NAME β¨
std::filesystem::path::stem β literally just std::filesystem::path::stem, no cap, that's the whole name π«Ά
πΈ Synopsis πΈ
path stem() const; (since C++17)
so here's the vibe: this bad boy returns the filename identified by the generic-format path stripped of its extension. that's it. that's the whole job. π
more specifically β and this is the part people always get wrong, so pay attention β it returns the substring from the beginning of filename() up to and not including the last period (.) character, with the following exceptions:
- π¦ If the first character in the filename is a period, that period is ignored (a filename like
".profile"is not treated as an extension). so dotfiles keep their dot. we respect the dotfiles here. - π¦ If the filename is one of the special filesystem components dot or dot-dot, or if it has no periods, the function returns the entire
filename(). no periods? no problem, you get everything back.
π§ Parameters π§
(none) β she takes nothing. she needs nothing. main character energy fr. β¨
π Return value π
The stem of the filename identified by the path (i.e. the filename without the final extension). lowkey the most useful little string you'll ever grab. π₯
π Exceptions π
May throw implementation-defined exceptions. so like... it might be messy, and it's up to your implementation to tell you how. not me being vague, that's just what the page says π
π Example π
// Run this code
#include <filesystem>
#include <iostream>
namespace fs = std::filesystem;
int main()
{
for (const fs::path p : {"/foo/bar.txt", "/foo/.bar", "foo.bar.baz.tar"})
std::cout << "path: " << p << ", stem: " << p.stem() << '\n';
std::cout << '\n';
for (fs::path p = "foo.bar.baz.tar"; !p.extension().empty(); p = p.stem())
std::cout << "path: " << p << ", extension: " << p.extension() << '\n';
}
β Output β
path: "/foo/bar.txt", stem: "bar"
path: "/foo/.bar", stem: ".bar"
path: "foo.bar.baz.tar", stem: "foo.bar.baz"
path: "foo.bar.baz.tar", extension: ".tar"
path: "foo.bar.baz", extension: ".baz"
path: "foo.bar", extension: ".bar"
look at that second loop bestie β it just keeps calling stem() on itself until extension() is empty, and you get to watch the extension peel off one layer at a time. it's giving onion. it's giving satisfying. obsessed. π§
β¨
π«Ά See also π«Ά
filenameβ returns the filename path component (public member function)extensionβ returns the file extension path component (public member function)
the little trio: filename() gives you the whole name, extension() gives you the tail, and stem() gives you everything but the tail. iykyk π
real talk though: exceptions are implementation-defined, so don't come crying to me if your compiler has opinions. go read its docs. π
and that's the page, babe! brought to you by http://cppreference.com, dated 2024.06.10 β mwah, go write something slay π πΈπ¦
π¦ where this page comes from
- nixpkgs unstable: stdman 2024.07.05
- opensuse-leap 16.0: stdman 2024.07.05-bp160.1.9 Β· MIT
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms