I'm trying to write the following C++ function, however I cannot figure out how to format a std::filesystem::path
object.
const auto load_test_file(std::filesystem::path filename) {
std::ifstream ifile(filename, std::ios::in | std::ios::binary);
if(!ifile.is_open()) {
const auto error_message = std::format("failed to open file {}", filename.string());
throw std::runtime_error(error_message.c_str());
}
// do some stuff here
}
I am using std::filesystem::path
as the type of the argument to this function, because a std::string_view
is not compatiable with the constructor of std::ifstream
. (Or std::ofstream
, for that matter.)
This reason for this is (AFAIK) that the underlying C API requires a null-terminated string, which a std::string_view
does not guarantee.
I don't want to pass a std::string&
, because this is inefficient if a char*
is used in place of an already constructed std::string
object. (Although to be honest in this context, where I am writing a unit test, this is really irrelevant.)
Therefore my understanding is a std::filesystem::path
is the most correct type to use in this situation.
Is there a way to format a std::filesystem::path
?
I'm trying to write the following C++ function, however I cannot figure out how to format a std::filesystem::path
object.
const auto load_test_file(std::filesystem::path filename) {
std::ifstream ifile(filename, std::ios::in | std::ios::binary);
if(!ifile.is_open()) {
const auto error_message = std::format("failed to open file {}", filename.string());
throw std::runtime_error(error_message.c_str());
}
// do some stuff here
}
I am using std::filesystem::path
as the type of the argument to this function, because a std::string_view
is not compatiable with the constructor of std::ifstream
. (Or std::ofstream
, for that matter.)
This reason for this is (AFAIK) that the underlying C API requires a null-terminated string, which a std::string_view
does not guarantee.
I don't want to pass a std::string&
, because this is inefficient if a char*
is used in place of an already constructed std::string
object. (Although to be honest in this context, where I am writing a unit test, this is really irrelevant.)
Therefore my understanding is a std::filesystem::path
is the most correct type to use in this situation.
Is there a way to format a std::filesystem::path
?
According to https://en.cppreference/w/cpp/compiler_support via Ctrl+f 'std::formatter<std::filesystem::path>' it seems it's not supported by any compiler at the moment.
However, if you can use external libraries, consider using fmt:
#include <filesystem>
#include <fmt/std.h>
int main()
{
std::filesystem::path path{"/home/user/a_path"};
fmt::print("fmt: {}\n", path);
return 0;
}
https://godbolt./z/9rbsv1oGc
std::string
as the function argument type is probably the wrong choice, no? – user2138149 Commented Mar 6 at 14:14std::filesysyem::path
. The link I posted has some examples for that. If it's something else then I missunderstood the issue. – wohlstad Commented Mar 6 at 14:16path
is the correct type to use if that is what the string represents, if there is not a built in formatter forpath
then you might as well fall back to using astring
. Bothpath
andstring
are going to copy achar*
so you are not gaining any performance by usingpath
instead ofstring
– NathanOliver Commented Mar 6 at 14:17std::format
support forstd::filesystem::path
is only available in C++26 which is not yet implemented in all three compilers. – 康桓瑋 Commented Mar 6 at 14:28