【问题标题】:CStdioFile problems with encoding on read fileCStdioFile 读取文件的编码问题
【发布时间】:2018-07-16 18:37:20
【问题描述】:

我无法使用 CStdioFile 正确读取文件。

我打开notepad.exe,输入àèìòùáéíóú并保存两次,一次将编码设置为ANSI(真的是CP-1252),其他设置为UTF-8

然后我尝试使用以下代码块从 MFC 读取它

BOOL ReadAllFileContent(const CString &FilePath, CString *fileContent)
{
    CString sLine;
    BOOL isSuccess = false;

    CStdioFile input;
    isSuccess = input.Open(FilePath, CFile::modeRead);
    if (isSuccess) {
        while (input.ReadString(sLine)) {
            fileContent->Append(sLine);
        }
        input.Close();
    }
    return isSuccess;
}

当我使用 ANSI 文件调用它时,我得到了预期的结果 àèìòùáéíóú 但是当我尝试读取 UTF8 编码文件时,我得到了à èìòùáéíóú

我希望我的函数适用于所有文件,无论编码如何。

为什么我需要实施?

.EDIT.

  • 很遗憾,在实际应用中,文件来自外部应用,因此无法更改文件编码。我必须能够同时读取 UTF-8 和 CP-1252 文件。
  • 任何文件都是有效的ANSI,记事本告诉ANSI实际上是Windows-1252编码。
  • 根据here 提供的示例,我找到了一种阅读UTF-8CP-1252 的方法。虽然可行,但我需要传递我事先不知道的文件编码。

谢谢!

【问题讨论】:

  • 几年前,我记得 MFC CStdioFile 是有限的,不能很好地与 Unicode 配合使用。我在 CodeProject 上找到了更好的替代品:CStdioFileEx。你可能想看看它;它在几个项目中运行良好。我不知道更现代的 MFC 版本是否改进了CStdioFile
  • “我希望我的函数适用于所有文件,无论编码如何。” -- 由于纯文本文件格式的限制,这样的函数根本不可能,它不提供定义编码的标准方法。如果幸运的话,该文件以 Unicode BOM 开头,但对于 ANSI 文件,您就不走运了。您可以假设操作系统定义的“非 Unicode 程序的当前代码页”,或者让用户明确输入代码页。

标签: c++ visual-c++ unicode file-io mfc


【解决方案1】:

我个人使用此处宣传的课程:

https://www.codeproject.com/Articles/7958/CTextFileDocument

它对读取和写入各种编码的文本文件具有出色的支持,包括各种风格的 unicode。

我没有遇到过问题。

【讨论】:

  • 我确信这可能是处理 unicode 文件的最佳方式,但我想尽可能避免使用外部库
  • 它是一个单一的源和头文件。不是图书馆。查看源代码并了解他们是如何做到的。否则,您基本上是在重新发明轮子。 ?
  • 我已经测试这个库几天了,但不幸的是,CTextFileDocument 并不足以自动检测编码。如果文件没有 BOM,它将始终检测为 ASCII。尽管自动检测很差(参见ReadDOM()),但我认为这是一个很好的包装类,它简化了很多编码工作,但它并没有解决我的问题。
猜你喜欢
  • 2015-07-27
  • 2014-04-18
  • 2014-01-05
  • 1970-01-01
  • 2016-08-02
  • 2012-11-14
  • 1970-01-01
  • 1970-01-01
  • 2014-03-12
相关资源
最近更新 更多