【问题标题】:What character encoding is used by fopen() or open()?fopen() 或 open() 使用什么字符编码?
【发布时间】:2018-06-11 03:37:18
【问题描述】:

当您使用像fopen() 这样的函数时,您必须将文件名的字符串参数传递给它。我想知道这个字符串的字符编码应该是什么。

这个问题已经被问过here,但它有矛盾的答案。一个答案如下:

这取决于系统区域设置。查看“语言环境”的输出 命令。如果变量以 UTF-8 结尾,那么您的语言环境是 UTF-8。 大多数现代 linux 将使用 UTF-8。虽然安德鲁是正确的 从技术上讲,它只是一个字节字符串,如果你不匹配 系统语言环境 某些程序可能无法正常工作,它会 无法获得正确的用户输入等。最好坚持 UTF-8。

而另一个答案如下:

Linux 上的文件系统调用与编码无关,即它们不 (需要)了解特定的编码。就他们而言 有关,文件名参数指向的字节串是 按原样传递给文件系统。文件系统期望 文件名采用正确的编码(通常是 UTF-8,如前所述 马修·塔尔伯特)。

这意味着您通常不需要做任何事情(文件名是 视为不透明的字节字符串),但这实际上取决于您在哪里 接收文件名,以及是否需要操作 任何方式的文件名。

哪个答案是正确的?

【问题讨论】:

  • 您引用的第一个答案显然是错误的。它不依赖于“系统语言环境”。一开始就没有系统语言环境之类的东西。只有用户区域设置。

标签: c linux character-encoding


【解决方案1】:

它们在某些方面都是正确的。

传递给文件系统调用的字符串是一串字节,空字节标记字符串的结尾,'/'用于分隔路径组件。在文件名段中,字节的含义对文件系统来说并不重要——它们只是一个字节序列。

如何显示构成文件名的字节取决于用于显示它们的设备。如果名称使用带有非 ASCII 字符的 UTF-8,则使用 ISO 8859-15(或美国顽固的居民使用 8859-1)打印该数据会产生乱码,通常包括字节范围 0x80 .. 0x9F 中的 C1 控制字节。如果名称使用 8859-15 和非 ASCII 字符,则会出现无效的 UTF-8 序列,并且您将获得难以辨认或无意义的数据显示(问号或其他无效 UTF-8 序列的指示)。

【讨论】:

  • 例外情况是以 16 位字符存储名称的文件系统;然后挂载选项iocharset 告诉如何将 16 位字符转换为 8 位字符序列,反之亦然。 (例如,这会影响 VFAT 上的长文件名。NTFS 使用 nls 挂载选项来代替,因为显然,如果 MS 可以避免它,那么它所做的一切都不是标准的。)
  • @NominalAnimal:MS 究竟是如何参与 Linux 文件系统挂载选项的命名的? VFAT 驱动程序和 NTFS3G 都不是来自 Microsoft。这更像是“在 Linux 上,没有两个人在不同的实现中以兼容的方式做同样的事情”——问问那些试图在 DE 混乱中整理秩序的可怜的 FreeDesktop 家伙。
  • @MatteoItalia:不,你错了。 NTFS 最初使用iocharset 挂载选项,但很快就被弃用,取而代之的是nls 选项。 Linux NTFS 驱动程序可以 使用这两个选项,但代码专门检查iocharset 以显示弃用错误。像所有其他文件系统一样使用 nls= 而不是 iocharset= 的唯一原因是为了安抚微软,他们在文档中使用“NLS”和“codepage”而不是字符集。 NTFS 开发人员似乎对与 Microsoft 合作比对 Linux 更感兴趣:参见例如Tuxera历史。
  • (如果有人不清楚,Anton Altaparmakov 是 Linux NTFS fs 驱动程序维护者,Tuxera.com is marked as the maintainer website。祝你好运尝试获得任何补丁,甚至 允许使用 iocharset 挂载选项,在 fs'es 之间统一它。不会发生;会比你为它编写五行补丁更快。请尝试一下。)
  • 这实际上很有趣,该选项自 2005 年之前名义上已被弃用(就犯罪行的 git 历史而言),但今天 - 13 多年后 - 它仍然可以正常工作,它只是吐出一条恼人的信息;他们对这种弃用并不那么认真。删除烦人的消息确实是一个 5 行补丁,我很惊讶没有人打扰,我会尝试在 LKML 上询问。我仍然不相信阴谋论,我已经看到了足够多关于“正确的事情”的小争吵,以至于认为我们完全有能力自我造成这种伤害。
猜你喜欢
  • 2011-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-07
  • 1970-01-01
  • 2012-02-23
相关资源
最近更新 更多