【问题标题】:Can't read a UTF8 encoded file using fopen(file, "r,ccs=UTF-8")无法使用 fopen(file, "r,ccs=UTF-8") 读取 UTF8 编码文件
【发布时间】:2012-05-17 09:38:18
【问题描述】:

使用 fopen 打开文件时,我使用 ccs=encoding(如 MSDN 中所述)将编码设置为 UTF-8。

写入文件时它工作正常

wchar_t* unicode_text = L"こんにちは";
FILE* f = fopen("C:\\test.txt", "w,ccs=UTF-8");
fwprintf(f, L"%s\n", unicode_text);
fclose(f);

当我在文本编辑器中打开文件时,unicode 会按原样显示。 但是在尝试从创建的文件中读取时,未检测到 UTF-8 编码:

wchar_t buffer[1000];
FILE* f = fopen("C:\\test.txt", "r,ccs=UTF-8");
fgetws(buffer, 1000, f);
fclose(f);

MessageBoxW(0, buffer, 0, 0);

这会在消息框中显示“ããã«ã¡ã¯”。

为什么会这样? ccs=UTF-8 是否只在打开文件写入时有效?

【问题讨论】:

  • ããã«ã¡ã¯ 绝对不是 ASCII。事实上,它完全是-ASCII。
  • 很公平,我已经删除了关于 ASCII 的部分。
  • 你为什么要尝试做这种丑陋的非标准黑客,而不是仅仅要求以 UTF-8 语言环境开头或使用iconv(干净/便携的方式)?

标签: c windows visual-studio fopen


【解决方案1】:

文档暗示 UTF-8 编码仅可用于写入(强调我的):

在 Visual C++ 2005 中,fopen 支持 Unicode 文件流。 打开新文件覆盖现有文件时,可以将指定所需编码的标志传递给 fopen,如下所示:

请注意,“读取现有文件”明显不存在。

【讨论】:

  • 感谢您指出这一点。然后我将使用 fgets+mbstowcs。
  • MSDN 中说:“如果文件已经存在并且打开以进行读取或附加,则使用字节顺序标记 (BOM) 来确定正确的编码。...仅当不存在 BOM 或文件是新文件时才使用该标志。"
  • @alexander,正如我所说的,它“暗示”而不是确定的。我使用该语句来描述打开文件进行覆盖时会发生什么。
【解决方案2】:

试试这个

#include <locale.h>

setlocale(LC_ALL, "Japanese");

【讨论】:

  • 我认为问题在于缺少对setlocale 的调用可能是对的,但"Japanese" 不是正确的论点。
  • 怎么样,在我环境中的控制台应用程序中,setlocale (LC_ALL," Japanese "); 能够通过wprintf (L"% s ", buffer); 无垃圾地输出到控制台。所以,fgetws (buffer, 1000, f); 我认为这是能够正确阅读的行为。是MessageBoxWsetlocale (LC_ALL," Japanese ")在日文版vs2010的环境中可能是另一个问题,因为即使你不设置即使你设置了也能正常显示。
  • 问题可能是默认字体。
【解决方案3】:

fgets,fgetws

fgetws 将宽字符参数 str 读取为多字节字符 根据流是否是字符串或宽字符串 以文本模式或二进制模式打开,

如果你尝试“rb”。

【讨论】:

    【解决方案4】:

    这可能就像从文本中剥离 BOM 一样简单。看起来您的文本框中显示的前三个字符(“”)是 UTF-8 文件的 BOM:

    http://en.wikipedia.org/wiki/Byte_order_mark#Representations_of_byte_order_marks_by_encoding

    【讨论】:

      猜你喜欢
      • 2016-08-14
      • 2022-01-11
      • 2011-07-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-22
      • 2011-07-26
      • 1970-01-01
      相关资源
      最近更新 更多