我读取和使用unicode文件内容时遇到了问题。
我正在使用一个unicode发布版本,并尝试从一个unicode文件中读取内容,但数据包含奇怪的字符,我似乎找不到将数据转换为ASCII的方法。
我正在使用fgets
。我尝试过fgetws
、WideCharToMultiByte
以及其他一些在其他文章和帖子中找到的函数,但都没有成功。
我读取和使用unicode文件内容时遇到了问题。
我正在使用一个unicode发布版本,并尝试从一个unicode文件中读取内容,但数据包含奇怪的字符,我似乎找不到将数据转换为ASCII的方法。
我正在使用fgets
。我尝试过fgetws
、WideCharToMultiByte
以及其他一些在其他文章和帖子中找到的函数,但都没有成功。
wopen
或_wfopen
作为二进制文件打开文件WideCharToMultiByte
和CP_UTF8
将其转换为wchar_t
wchar_t
数组并使用_swab
wchar_t
数组即可完成此外(如果您使用较新的Visual Studio),您可以利用_wfopen
的MS扩展。它可以将编码作为模式的一部分(类似于_wfopen(L"newfile.txt", L"rw, ccs=<encoding>");
,其中编码为UTF-8或UTF-16LE)。它还可以根据BOM检测编码。
警告:要跨平台存在问题,wchar_t
可以是2或4个字节,转换例程不可移植...
有用的链接:
处理字符集的预期方式是让区域设置系统来处理。
在打开流之前,您必须设置正确的区域设置。
另外,您标记了问题为C++,但您写了有关fgets和fgetws而不是IOStreams;您的问题是C ++还是C?
C语言:
#include <locale.h>
setlocale(LC_ALL, ""); /* at least LC_CTYPE */
对于C++
#include <locale>
std::locale::global(std::locale(""));
如果您的环境正确设置了Unicode,则宽IO(wstream,fgetws)应该可以正常工作。如果没有,则必须更改您的环境(对于Windows,我不知道它是如何工作的;对于Unix,设置LC_ALL变量是一种方法,请参见locale -a
以获取支持的值)。或者,将空字符串替换为区域设置也可以,但这样您就在程序中硬编码了区域设置,您的用户可能不会欣赏。
如果您的系统不支持足够的区域设置,在C++中有可能自己编写转换facet。但这超出了本答案的范围。
为了回答这个问题,我们需要更多的信息(例如,您是要将Unicode文件读入char
缓冲区还是wchar_t
缓冲区?文件使用什么编码?),但现在您可能想确保您不会遇到this issue,如果您的文件是Unicode并且您正在文本模式下使用fgetws
。
当Unicode流I/O函数以文本模式操作时,源或目标流被认为是一系列多字节字符。因此,Unicode流输入函数将多字节字符转换为宽字符(如同调用mbtowc函数一样)。出于同样的原因,Unicode流输出函数将宽字符转换为多字节字符(如同调用wctomb函数一样)。
Unicode 是将数字代码映射为字符的过程。在 Unicode 之前的步骤是文件的编码:如何将一些连续的字节转换为数字代码?您必须检查文件是否以大端、小端或其他方式存储。
通常,BOM(字节顺序标记)被写入文件的前两个字节:FF FE 或 FE FF。
首先:我假设您正在尝试读取UTF8编码的Unicode(因为您可以读取一些字符)。例如,您可以在Notpad++中检查此信息。
对于您的问题-我建议使用某种库。您可以尝试 QT, QFile支持Unicode(以及库的其余部分)。
如果这太困难了,请使用特殊的unicode库,例如:http://utfcpp.sourceforge.net/。
并学习有关Unicode的知识:http://en.wikipedia.org/wiki/Unicode。在那里,您会找到有关不同Unicode编码的参考资料。
即使是UTF-8,你也不能可靠地将Unicode转换为ASCII。字符集(Unicode文档中的“平面”)无法映射回ASCII - 这就是Unicode存在的原因。