将字符串转换为标准文件系统路径

19

一个文件路径被作为一个字符串传递。我该如何将这个字符串转换成std::filesystem::path?举个例子:

#include <filesystem>

std::string inputPath = "a/custom/path.ext";
const std::filesystem::path path = inputPath; // Is this assignment safe?

1
我认为这个链接http://en.cppreference.com/w/cpp/filesystem/path/operator%3D是可以的。 - Ankur Jyoti Phukan
1
调用path constructor 4从源提供的字符序列(4)构造路径,该源是指向以空字符/宽字符结尾的字符序列的指针或输入迭代器,一个std::basic_string [...] - zett42
@AnkurJyotiPhukan 不,这不是作业。 - Barry
2个回答

26
是的,这个结构是安全的。
const std::filesystem::path path = inputPath; // Is this assignment safe?

那不是赋值,那是复制初始化。您正在调用此构造函数

template< class Source >
path( const Source& source );

接收:

从源字符序列 (4) 构造路径,该字符序列是指向 null-terminated 字符/宽字符序列的指针或输入迭代器,一个 std::basic_stringstd::basic_string_view

所以你没问题了。此外,如果你不能从 std::string 构造出 filesystem::path,那就太奇怪了。


6

我知道这是一个5年前的问题,但由于它仍然是搜索“字符串到filesystem :: path”的顶部结果,我认为需要在Windows上的用法方面进行一些额外的评论(尽管原始问题可能是隐含地专注于Linux,从所选路径分隔符来判断)。

对于Windows系统,从字符串隐式构造filesystem :: path 在编码方面不安全(尽管根据标准是合法的)。如果您有一个包含非ASCII字符的std :: string路径,则必须非常清楚它是使用本地代码页还是UTF-8编码的(在Linux下没有这样的区别)。问题中显示的隐式构造将假定使用本地代码页进行编码,而许多第三方库将默认使用UTF-8作为标准(例如,QT中的QString :: toStdString()返回UTF-8;应该预期gRPC / protobuf中的字符串为UTF-8等)。因此,您必须非常小心,不要混淆这些:

const std::string path_as_string = "\xe4\xb8\xad"; //chinese character Zhong in UTF-8
const std::filesystem::path wrong_path = path_as_string; //looks innocent, but incorrect encoding is used!

std::ofstream stream;
stream.open(std::filesystem::current_path() / wrong_path); //create a file with the broken name
stream.close();

在这种情况下构建路径的正确方法是:
const std::filesystem::path correct_path = std::filesystem::u8path(path_as_string);

请注意,这是一个完全有效的路径,您可以使用常规应用程序或Windows资源管理器轻松创建包含此类字符的文件。由于错误转换的潜力很高,在当前情况下,我认为对于Windows开发而言最好不要有任何隐式构造函数,但请求在STL实现中禁用该行为的选项已被拒绝并参考了标准。另一方面,似乎Windows将来会慢慢转向UTF-8作为默认代码页(例如,请参阅此评论)。在那之前,上述注意事项应该被考虑进去。

是的,非常好的观点。谢谢您。 - J Evans

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接