【问题标题】:c-file encoded in utf-16 is not read properly by gccgcc 无法正确读取以 utf-16 编码的 c 文件
【发布时间】:2021-03-15 17:16:41
【问题描述】:

在进行一些编码测试时,我保存了一个编码为“UTF-16 LE”的 c 文件(使用 sublimeText)。

c 文件包含以下内容:

#include <stdio.h>

void main() {
    char* letter = "é";
    printf("%s\n", letter);
}

用 gcc 编译这个文件返回错误:

test.c:1:3: error: invalid preprocessing directive #i; did you mean #if?
    1 | # i n c l u d e   < s t d i o . h >

就好像gcc在读取c文件时在每个字符前插入了一个空格。

我的问题是:我们可以提交以“utf-8”以外的其他格式编码的 c 文件吗?为什么 gcc 无法检测到我的文件的编码并正确读取它?

【问题讨论】:

  • "就好像 gcc 在读取 c 文件时在每个字符前插入了一个空格" - 您创建了一个以 UTF-16 编码的源文件,它使用 2 字节字符单位。 gcc 假设 1 字节字符读取它。由于字符在 ASCII 范围内,“空格”是 0x00 的高字节。不要将 UTF-16 用于源文件(至少前面没有 BOM),大多数编译器无法处理它。 “为什么 gcc 无法检测到我的文件的编码并正确读取它?” - 没有 BOM,您是否意识到这有多么困难,因为世界?
  • @RemyLebeau 文件是utf-16 Little Endian,里面有对应的BOM
  • 即使使用 BOM,也不能保证编译器将支持 Unicode 编码的源文件。检查编译器的文档。在这种情况下,请参阅 g++ compiling sources in UTF-16 encodingHow should I use g++'s -finput-charset compiler option correctly in order to compile a non-UTF-8 source file?

标签: gcc utf-8 character-encoding utf-16


【解决方案1】:

因为设计选择。

来自GNU Manual, Character-sets

目前,GNU CPP 没有实现从任意文件编码到源字符集的转换。使用纯 ASCII 或 UTF-8 以外的任何编码(cmets 除外)都会导致错误。即使非 ASCII 字符仅出现在 cmets 中,使用非 ASCII 严格超集的编码(例如 Shift JIS)也可能导致错误。我们计划在不久的将来解决这个问题。

GCC 是为创建 GNU 而生的,因此来自 Unix 世界,UTF16 不是允许的字符集(对于标准文件,GNU 在不同程序之间传递源文件,例如 CPP 预处理器,GCC 编译器等)。

还有,谁使用 UTF16 作为来源?而对于 C,它讨厌字符串中的所有 \0?源代码的编码与程序无关(并为读取文件、打印字符串等做默认语言环境)。

如果它引起问题,只需使用预处理器(这并不罕见),将源代码更改为 gcc 可用代码(但对您隐藏,因此您可以继续以 UTF16 编辑)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-28
    • 2012-06-12
    • 1970-01-01
    • 2021-03-09
    • 1970-01-01
    • 1970-01-01
    • 2013-04-30
    • 2014-09-07
    相关资源
    最近更新 更多