读取Unicode文件

时间:2009-07-16 16:46:09

标签: c++ file unicode text

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

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

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

6 个答案:

答案 0 :(得分:7)

因为你提到了WideCharToMultiByte,我会假设你正在处理Windows。

  

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

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

所以你的最终缓冲区必须是wchar_t(或WCHARCStringW,同样的事情。)

所以你的文件可能是utf-16,或utf-8(utf-32很少见)。 对于utf-16,结束也可能很重要。如果有一个物料清单可以帮助很多。

快速步骤:

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

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

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

有用的链接:

答案 1 :(得分:1)

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

  

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

答案 2 :(得分:1)

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

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

答案 3 :(得分:1)

处理字符集的预期方法是让语言环境系统执行此操作。

您必须在打开流之前设置正确的区域设置。

顺便说一句,你标记了你的问题C ++,你写了关于fgets和fgetws但没有 输入输出流;你的问题是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 :(得分:0)

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

中查看此内容

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

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

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

答案 5 :(得分:0)

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