fstream :: open()在Windows上,Unicode或Non-Ascii字符不起作用(使用std :: ios :: out)

在C ++项目中,我想打开一个文件( fstream::open() )(这似乎是一个主要的问题)。 我的程序的Windows版本失败了。

  • 文件“ä”(UTF-8 0xC3 0xA4)

     std::string s = ...; //Convert s std::fstream f; f.open(s.c_str(), std::ios::binary | std::ios::in); //Works (f.is_open() == true) f.close(); f.open(s.c_str(), std::ios::binary | std::ios::in | std::ios::out); //Doesn't work 

    strings是UTF-8编码,但是然后从UTF-8转换为Latin1(0xE4)。 我正在使用Qt,所以QString::fromUtf8(s.c_str()).toLocal8Bit().constData()

    为什么我可以打开文件阅读,但不能写?

  • 文件“и”(UTF-8 0xD0 0xB8)

    相同的代码,根本不起作用。

看来,这个字符不适合Windows-1252字符集。 我如何打开这样的Fstream(我没有使用MSVC,所以没有fstream::open(const wchar_t*, ios_base::openmode) )?

在STL的Microsoft实现中,有一个非标准的扩展(过载)允许unicode支持UTF-16编码的字符串。

只需将UTF-16编码的std :: wstring传递给fstream :: open()即可。 这是使其与fstream合作的唯一方法。

你可以阅读更多关于我发现的最简单的方法来支持windows上的unicode这里: http : //utf8everywhere.org/

在Windows上使用标准API(如std :: fstream),如果文件名可以使用当前设置的“ANSI代码页”(CP_ACP)进行编码,则只能打开一个文件。

这意味着在Windows上可能存在无法使用这些API打开的文件。 除非Microsoft实现了将CP_ACP设置为CP_UTF8的支持,否则不能使用Microsoft的CRT或C ++标准库实现。

(Windows有一个称为“短”文件名的功能,当启用时,驱动器上的每个文件都有一个可以通过标准API使用的ASCII文件名,但是这个功能已经消失,所以它不能代表一个可行的解决方案。