如何用 unicode 文件名打开 std: : fstream (ofstream 或 ifstream) ?

你不会想到像用 Windows 应用程序的 C++标准程式库打开一个文件这样简单的事情是很棘手的... ... 但是看起来是这样的。这里的 Unicode 指的是 UTF-8,但是我可以转换成 UTF-16或者其他什么,关键是从 Unicode 文件名中获得一个离流实例。在我破解我自己的解决方案之前,有没有更好的路线?尤其是跨站台的?

69466 次浏览

Visual C + + 的当前版本 std: : basic _ fstream 有一个 open()方法,该方法根据 http://msdn.microsoft.com/en-us/library/4dx08bh4.aspx接受 wchar _ t * 。

该 C++标准程式库不支持 Unicode 编码,不要求 charwchar_t采用 Unicode 编码。

在 Windows 上,wchar_t是 UTF-16,但是在标准库中没有对 UTF-8文件名的直接支持(在 Windows 上,char数据类型不是 Unicode)

使用 MSVC (也就是 Microsoft STL) ,提供了一个文件流的构造函数,该构造函数采用 const wchar_t*文件名,允许您按以下方式创建流:

wchar_t const name[] = L"filename.txt";
std::fstream file(name);

但是,C + + 11标准没有指定此重载(它只保证基于 char的版本的存在)。它也没有出现在替代 STL 实现中,比如 GCC 针对 MinGW (- w64)的 libstdc + + ,在 g + + 4.8. x 版本中。

注意,就像 Windows 上的 char不是 UTF8一样,在其他操作系统上的 wchar_t可能不是 UTF16。所以总的来说,这不太可能是便携式的。打开一个给定 wchar_t文件名的流不是根据标准定义的,并且在 char中指定文件名可能很困难,因为不同操作系统使用的字符编码是不同的。

使用 std::wofstreamstd::wifstreamstd::wfstream。他们接受 Unicode 文件名。文件名必须是 wstring,数组的 wchar_t,或者它必须有 _T()宏,或前缀 L之前的文本。

看看 加速,空档:

#include <boost/nowide/fstream.hpp>
#include <boost/nowide/cout.hpp>
using boost::nowide::ifstream;
using boost::nowide::cout;


// #include <fstream>
// #include <iostream>
// using std::ifstream;
// using std::cout;


#include <string>


int main() {
ifstream f("UTF-8 (e.g. ß).txt");
std::string line;
std::getline(f, line);
cout << "UTF-8 content: " << line;
}

如果你使用 Qt 和 std::ifstream混合:

return std::wstring(reinterpret_cast<const wchar_t*>(qString.utf16()));

请注意,std::basic_ifstream构造函数通常不接受 const w_char*,而是接受 在 STL 的 MS 实现中,它是这样做的。对于其他实现,您可能会调用 qString.utf8(),并使用 const char* ctor。

自 C + + 17以来,有一种跨平台的方法可以使用 文件系统: : 路径重载打开具有 Unicode 文件名的 std: : fstream:

std::ofstream out(std::filesystem::path(u8"こんにちは"));
out << "hello";

使用

wfstream

而不是

fstream

还有

wofstream

而不是

ofstream

诸如此类。 您可以在 Iosfwd头文件中找到这些信息。