你不会想象像使用C ++标准库为Windows应用程序打开文件那样基本的东西很棘手......但它似乎是。在这里,我的意思是UTF-8,但我可以转换为UTF-16或其他任何东西,重点是从Unicode文件名获取一个ofstream实例。在我推出自己的解决方案之前,这里有一条首选路线吗?特别是跨平台的?

有帮助吗?

解决方案

C ++标准库不支持Unicode。 char wchar_t 不需要是Unicode编码。

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

使用MSVC(以及Microsoft STL),提供了一个文件流构造函数,它使用 const wchar_t * 文件名,允许您创建流:

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

但是,C ++ 11标准未指定此重载(它仅保证存在基于 char 的版本)。它也不存在于替代STL实现中,如GCC的用于MinGW的libstdc ++(-w64),从版本g ++ 4.8.x开始。

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

其他提示

当前版本的Visual C ++ std :: basic_fstream有一个 open()方法,根据 http://msdn.microsoft.com/en-us/library/4dx08bh4.aspx

从C ++ 17开始,有一种跨平台的方法可以使用 std :: filesystem :: path 重载。在C ++ 20之前,您可以使用从UTF-8字符串创建路径。的std ::文件系统:: u8path 。例如:

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

在C ++ 20之后,您可以通过将UTF-8传递给构造函数来创建路径: std :: filesystem :: path(u8&quot;&#12371;&#12435;&#12395;&# 12385;&#12399;&quot;)(u8path将被弃用)。

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

查看 Boost.Nowide

#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;
}

如果您使用的是与 std :: ifstream 混合的Qt:

return std::wstring(reinterpret_cast<const wchar_t*>(qString.utf16()));
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top