【发布时间】:2010-11-25 07:11:09
【问题描述】:
我正在用 C 语言编写一个小型应用程序,它读取一个简单的文本文件,然后逐行输出。问题是文本文件包含特殊字符,如 Æ、Ø 和 Å 等。当我在终端中运行程序时,这些字符的输出用“?”表示。
有简单的解决方法吗?
【问题讨论】:
标签: c macos encoding utf-8 terminal
我正在用 C 语言编写一个小型应用程序,它读取一个简单的文本文件,然后逐行输出。问题是文本文件包含特殊字符,如 Æ、Ø 和 Å 等。当我在终端中运行程序时,这些字符的输出用“?”表示。
有简单的解决方法吗?
【问题讨论】:
标签: c macos encoding utf-8 terminal
第一件事:
确保您的终端可以处理 UTF-8 输出。拥有正确的语言环境设置和操作语言环境数据可以自动为您打开和转换大量文件……这取决于您在做什么。
记住,UTF-8 中代码点或字符的宽度是可变的。这意味着您不能只寻找一个字节并像使用 ASCII 一样开始阅读……因为您可能会落在代码点的中间。在某些情况下,好的库可以做到这一点。
这里有一些代码(不是我的),演示了 C 中 UTF-8 文件读取和宽字符处理的一些用法。
#include <stdio.h>
#include <wchar.h>
int main()
{
FILE *f = fopen("data.txt", "r, ccs=UTF-8");
if (!f)
return 1;
for (wint_t c; (c = fgetwc(f)) != WEOF;)
printf("%04X\n", c);
fclose(f);
return 0;
}
链接
【讨论】:
确保您不会意外丢失任何字节;一些 UTF-8 字符的长度超过一个字节(这就是重点),您需要保留它们。
将缓冲区的内容打印为十六进制会很有用,因此您可以检查实际读取了哪些字节:
static void print_buffer(const char *buffer, size_t length)
{
size_t i;
for(i = 0; i < length; i++)
printf("%02x ", (unsigned int) buffer[i]);
putchar('\n');
}
您可以在加载一个非常短的文件(仅包含几个字符)后执行此操作。
还要确保终端设置为正确的编码,以便将您的字符解释为 UTF-8。
【讨论】:
您的文本文件可能是 ISO-8559-1 编码的,但您的终端是 UTF-8。这种不匹配是处理面向字节的文本处理时的标准问题;其他 C 程序(例如标准的“cat”和“more”命令)会执行相同的操作,通常不会将其视为错误或需要修复的问题。
如果您想在 Unicode 字符级别而不是字节上进行操作,那很好,但您需要在整个程序中使用 wchar 而不是 char 作为字符类型,并为用户提供开关以指定传入文件的内容编码实际上是。 (虽然有时可以猜到,但不是很可靠。)
【讨论】:
我不知道它是否有帮助,但如果你确定终端和输入文件的编码是相同的,你可以尝试setlocale():
#include <locale.h>
…
setlocale(LC_CTYPE, "");
【讨论】:
setlocale(LC_CTYPE, "UTF-8");。尽管正确配置了 shell 环境,但必须成功读取文件。
setlocale(LC_CTYPE, ""),根据环境变量设置每个需要修改的locale部分。
"" 而不是 NULL。