3

在 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
    

    该字符串s是 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))?

4

2 回答 2

4

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

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

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

于 2012-05-14T04:30:22.633 回答
4

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

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

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

更新:Windows 10 增加了对将代码页设置为 UTF-8 的支持

于 2012-05-13T04:09:40.397 回答