【问题标题】:Read Unicode Files读取 Unicode 文件
【发布时间】:2010-11-11 10:50:09
【问题描述】:

我在阅读和使用 unicode 文件的内容时遇到问题。

我正在开发一个 unicode 版本,我正在尝试从 unicode 文件中读取内容,但数据包含奇怪的字符,我似乎无法找到将数据转换为 ASCII 的方法。

我正在使用fgets。我尝试了fgetwsWideCharToMultiByte,以及我在其他文章和帖子中找到的许多功能,但没有任何效果。

【问题讨论】:

  • 您可能想澄清“Unicode”的含义。 UTF-8? UTF-16?
  • 如果您发布相关代码并告诉我们您看到的结果与您的预期有何不同,这将有所帮助。
  • 请注意,您的文件中可能没有“奇怪字符”的 ASCII 表示形式。
  • 一个文件不是 unicode,它是 unicode 的某种编码(例如 UTF-8 或 latin-1)。文件的编码是什么?

标签: c++ file unicode text


【解决方案1】:

我们需要更多信息来回答这个问题(例如,您是想将 Unicode 文件读入char 缓冲区还是wchar_t 缓冲区?文件使用什么编码?),但现在如果您的文件是 Unicode 并且您在文本模式下使用 fgetws,您可能需要确保没有遇到 this issue

当 Unicode 流-I/O 函数在文本模式下运行, 源或目标流是 假设是一个多字节序列 人物。因此,Unicode 流输入函数转换 多字节字符到宽 字符(好像通过调用 mbtowc 函数)。出于同样的原因, Unicode 流输出函数 将宽字符转换为多字节 字符(好像通过调用 wctomb 函数)。

【讨论】:

    【解决方案2】:

    Unicode 是从数字代码到字符的映射。 Unicode 之前的步骤是文件的编码:如何将一些连续的字节转换为数字代码?您必须检查文件是否存储为 big-endian、little-endian 或其他格式。

    通常,BOM(字节顺序标记)作为文件中的前两个字节写入:FF FE 或 FE FF。

    【讨论】:

      【解决方案3】:

      处理字符集的预期方式是让语言环境系统来处理。

      您必须在打开直播之前设置正确的语言环境。

      顺便说一句,你标记了你的问题 C++,你写了关于 fgets 和 fgetws 但没有 IO流;你的问题是 C++ 还是 C?

      对于 C:

      #include <locale.h>
      setlocale(LC_ALL, ""); /* at least LC_CTYPE */
      

      对于 C++

      #include <locale>
      std::locale::global(std::locale(""));
      

      如果您的环境正确,那么宽 IO(wstream、fgetws)应该可以工作 设置为 Unicode。如果没有,你将不得不改变你的环境(我不 它如何在 Windows 下工作,对于 Unix,设置 LC_ALL 变量是 方式,请参阅locale -a 了解支持的值)。或者,更换 区域设置的空字符串也可以工作,但是你硬编码 您的程序中的语言环境,您的用户可能不会欣赏这一点。

      如果您的系统不支持适当的语言环境,则在 C++ 中具有 自己编写转换方面的可能性。但是那个外面 这个答案的范围。

      【讨论】:

        【解决方案4】:

        首先:我假设您正在尝试读取 UTF8 编码的 Unicode(因为您可以读取一些字符)。例如,您可以在 Notpad++ 中检查这一点

        对于您的问题 - 我建议使用某种库。你可以试试QT,QFile 支持 Unicode(以及库的其余部分)。

        如果太多,请使用特殊的 unicode 库,例如:http://utfcpp.sourceforge.net/

        了解 unicode:http://en.wikipedia.org/wiki/Unicode。在那里您会找到对不同 unicode 编码的引用。

        【讨论】:

          【解决方案5】:

          因为您提到 WideCharToMultiByte,所以我假设您正在处理 Windows。

          “从 unicode 文件中读取内容……找到将数据转换为 ASCII 的方法”

          这可能是个问题。如果您将 Unicode 转换为 ASCII(或其他遗留代码页),您将面临损坏/丢失数据的风险。 由于您正在“处理 unicode 发布版本”,因此您将希望阅读 Unicode 并保持 Unicode。

          所以你的最终缓冲区必须是wchar_t(或WCHAR,或CStringW,同样的东西)。

          所以您的文件可能是 utf-16 或 utf-8(utf-32 很少见)。 对于 utf-16,字节序也可能很重要。如果有一个 BOM 会很有帮助。

          快速步骤:

          • 使用wopen_wfopen 作为二进制文件打开文件
          • 读取第一个字节以使用 BOM 识别编码
          • 如果编码是utf-8,则读入一个字节数组并转换为wchar_tWideCharToMultiByteCP_UTF8
          • 如果编码是 utf-16be (big endian),则在 wchar_t 数组和 _swab 中读取
          • 如果编码是 utf-16le(小端序),则在 wchar_t 数组中读取并完成

          另外(如果您使用较新的 Visual Studio),您可以利用 MS 扩展至 _wfopen。它可以将编码作为模式的一部分(类似于_wfopen(L"newfile.txt", L"rw, ccs=&lt;encoding&gt;");,编码为UTF-8 或UTF-16LE)。它还可以根据BOM检测编码。

          警告:跨平台是有问题的,wchar_t 可以是 2 或 4 字节,转换例程不可移植...

          有用的链接:

          【讨论】:

          • 这正是传达的信息:“如果将 Unicode 转换为 ASCII(或其他遗留代码页),您将面临损坏/丢失数据的风险”
          • 对不起,我在这里的评论应该作为问题的答案发布。 你的答案是正确的。
          【解决方案6】:

          您无法可靠地将 Unicode(甚至 UTF-8)转换为 ASCII。字符集(Unicode 文档中的“平面”)不会映射回 ASCII - 这就是 Unicode 首先存在的原因。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2010-11-27
            • 2012-05-05
            • 1970-01-01
            • 2013-06-30
            • 2010-11-02
            • 2016-12-30
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多