一位客户抱怨我们的代码用于编写文件名中包含日文字符的文件,但不再适用于所有情况。我们一直只是使用良好的旧 char * 字符串来表示文件名,所以它曾经工作过让我有点震惊,而且我们没有做任何我知道应该让它停止工作的事情。我让他们向我发送了一个从我们的软件导出的带有嵌入文件名的文件,看起来这些字符串使用十六进制字符 82 和 83 作为双字节序列的第一个字符来表示日文字符。在网上闲逛让我相信这可能是 SHIFT_JIS 和/或 Windows 代码页 932。
在我看来,以前发生的事情是 fopen 和 ofstream::open 使用此代码页接受的文件名;现在只有 fopen 可以。我已经检查了 Visual Studio fopen 文档,但我没有看到任何提示可以将可接受的字符串传递给 fopen。
在短期内,我希望有人能为我阐明特定的 Windows fopen 与 ofstream::open 问题。从长远来看,我真的很想知道在 C++、Windows、Linux 和 OS X 上打开 Unicode(和其他?)文件名的公认方式。
编辑添加:我相信工作的打开是在“C”语言环境中完成的,而那些不工作的打开是在客户的默认语言环境中完成的。但是,这种情况已经存在多年了,旧版本的程序今天仍然可以在他们的系统上运行,所以这似乎无法解释我们所看到的问题。
更新:我向客户发送了一个小型测试程序。它已经验证 fopen 可以与 SHIFT_JIS 文件名一起正常工作,而 std::ofstream 不能。这是在 Visual Studio 2005 中,无论我使用的是默认语言环境还是“C”语言环境,都会发生这种情况。
如果有人对这种行为有解释(以及为什么它神秘地改变了——也许是 VS2005 的服务包?),我仍然很感兴趣,并希望将一个全面的“最佳实践”放在一起处理可移植 C++ 代码中的 Unicode 文件名。