How can I extract the file name and extension from a path in C++
Solution 1:
To extract a filename without extension, use boost::filesystem::path::stem instead of ugly std::string::find_last_of(".")
boost::filesystem::path p("c:/dir/dir/file.ext");
std::cout << "filename and extension : " << p.filename() << std::endl; // file.ext
std::cout << "filename only : " << p.stem() << std::endl; // file
Solution 2:
For C++17:
#include <filesystem>
std::filesystem::path p("c:/dir/dir/file.ext");
std::cout << "filename and extension: " << p.filename() << std::endl; // "file.ext"
std::cout << "filename only: " << p.stem() << std::endl; // "file"
Reference about filesystem: http://en.cppreference.com/w/cpp/filesystem
- std::filesystem::path::filename
- std::filesystem::path::stem
As suggested by @RoiDanto, for the output formatting, std::out
may surround the output with quotations, e.g.:
filename and extension: "file.ext"
You can convert std::filesystem::path
to std::string
by p.filename().string()
if that's what you need, e.g.:
filename and extension: file.ext
Solution 3:
If you want a safe way (i.e. portable between platforms and not putting assumptions on the path), I'd recommend to use boost::filesystem
.
It would look somehow like this:
boost::filesystem::path my_path( filename );
Then you can extract various data from this path. Here's the documentation of path object.
BTW: Also remember that in order to use path like
c:\foto\foto2003\shadow.gif
you need to escape the \
in a string literal:
const char* filename = "c:\\foto\\foto2003\\shadow.gif";
Or use /
instead:
const char* filename = "c:/foto/foto2003/shadow.gif";
This only applies to specifying literal strings in ""
quotes, the problem doesn't exist when you load paths from a file.
Solution 4:
You'll have to read your filenames from the file in std::string
. You can use the string extraction operator of std::ostream
. Once you have your filename in a std::string
, you can use the std::string::find_last_of
method to find the last separator.
Something like this:
std::ifstream input("file.log");
while (input)
{
std::string path;
input >> path;
size_t sep = path.find_last_of("\\/");
if (sep != std::string::npos)
path = path.substr(sep + 1, path.size() - sep - 1);
size_t dot = path.find_last_of(".");
if (dot != std::string::npos)
{
std::string name = path.substr(0, dot);
std::string ext = path.substr(dot, path.size() - dot);
}
else
{
std::string name = path;
std::string ext = "";
}
}