我的问题似乎让人们感到困惑。这是具体的:
我们的代码执行以下操作:
FILE * fout = _tfsopen(_T("丸穴種類.txt"), _T("w"), _SH_DENYNO);
_fputts(W2T(L"刃物種類\n"), fout);
fclose(fout);
在 MBCS 构建目标下,以上代码为代码页 932 生成了一个正确编码的文件(假设 932 是运行此代码页时的系统默认代码页)。
在 UNICODE 构建目标下,上面会产生一个充满 ???? 的垃圾文件。
我想定义一个符号,或使用编译器开关,或包含一个特殊的头文件,或链接到给定的库,以使上述内容在构建目标为 UNICODE 时继续工作而不更改源代码。
这是曾经存在的问题:
FILE*
流可以在 t(ranslated) 或 b(inary) 模式下打开。桌面应用程序可以编译为 UNICODE 或 MBCS(在 Windows 下)。如果我的应用程序是为 MBCS 编译的,那么将 MBCS 字符串写入“wt”流会生成一个格式正确的文本文件,其中包含系统代码页的 MBCS 文本(即“用于非 Unicode 软件的代码页”)。
因为我们的软件通常使用大多数字符串和流函数的 _t 版本,所以在 MBCS 构建中,输出主要由
puts(pszMBString)
或类似的东西处理putc
。由于pszMBString
已经在系统代码页中(例如,在日本机器上运行时为 932),字符串是逐字写出(尽管行终止符被自动按摩puts
)gets
。但是,如果我的应用程序是为 UNICODE 编译的,那么将 MBCS 字符串写入“wt”流会导致垃圾(大量“?????”字符)(即,我将 UNICODE 转换为系统的默认代码页,然后写入例如,使用
fwrite(pszNarrow, 1, length, stream)
) 将其发送到流。
我可以以二进制模式打开我的流,在这种情况下,我会得到正确的 MBCS 文本......但是,行终止符将不再是 PC 样式的 CR+LF,而是只会是 UNIX 样式的 LF。这是因为在二进制(非翻译)模式下,文件流不处理 LF->CR+LF 翻译。
但我真正需要的是能够生成与为 MBCS 编译时能够生成的完全相同的文件:使用系统代码页的正确行终止符和 MBCS 文本文件。
显然,我可以自己手动调整行终止符并使用二进制流。然而,这是一种非常具有侵入性的方法,因为我现在必须在整个系统中找到写入文本文件的每一段代码,并对其进行修改,以便它能够正确地完成所有这些工作。让我大吃一惊的是,UNICODE 目标比我们过去使用的 MBCS 目标更愚蠢/能力更差!当然有一种方法可以切换 C 库以显示“按原样输出窄字符串但正确处理行终止符,就像您在 MBCS 构建中所做的那样”?!