不幸std::filesystem
的是,在编写时并没有考虑到操作系统的兼容性,至少不像宣传的那样。
对于基于 Unix 的系统,我们需要 UTF8(u8"string"
或仅"string"
取决于编译器)
对于 Windows,我们需要 UTF16 ( L"string"
)
在 C++17 中,您可以使用filesystem::u8path
(由于某种原因在 C++20 中已弃用)。在 Windows 中,这会将 UTF8 转换为 UTF16。现在您可以将 UTF16 传递给 API。
#ifdef _WINDOWS_PLATFORM
//windows I/O setup
_setmode(_fileno(stdin), _O_WTEXT);
_setmode(_fileno(stdout), _O_WTEXT);
#endif
fs::path path = fs::u8path(u8"ελληνικά.txt");
#ifdef _WINDOWS_PLATFORM
std::wcout << "UTF16: " << path << std::endl;
#else
std::cout << "UTF8: " << path << std::endl;
#endif
或者使用您自己的宏为 Windows ( L"string"
) 设置 UTF16,为基于 Unix 的系统 (u8"string"
或只是"string"
) 设置 UTF8。确保UNICODE
为 Windows 定义。
#ifdef _WINDOWS_PLATFORM
#define _TEXT(quote) L##quote
#define _tcout std::wcout
#else
#define _TEXT(quote) u8##quote
#define _tcout std::cout
#endif
fs::path path(_TEXT("ελληνικά.txt"));
_tcout << path << std::endl;
另请参阅
https://en.cppreference.com/w/cpp/filesystem/path/native
注意,Visual Studio 有一个特殊的构造函数,
std::fstream
它允许使用 UTF16 文件名,并且它兼容 UTF8 读/写。例如,以下代码将在 Visual Studio 中工作:
fs::path utf16 = fs::u8path(u8"UTF8 filename ελληνικά.txt");
std::ofstream fout(utf16);
fout << u8"UTF8 content ελληνικά";
我不确定在 Windows 上运行的最新 gcc 版本是否支持这一点。