用C语言处理特殊字符(UTF-8编码)
我正在用C编写一个小应用程序,它读取一个简单的文本文件,然后逐行输出。问题是文本文件包含特殊字符,如Æ、Ø和Å等。当我在终端运行程序时,这些字符的输出用“?”表示用C语言处理特殊字符(UTF-8编码),c,macos,encoding,utf-8,terminal,C,Macos,Encoding,Utf 8,Terminal,我正在用C编写一个小应用程序,它读取一个简单的文本文件,然后逐行输出。问题是文本文件包含特殊字符,如Æ、Ø和Å等。当我在终端运行程序时,这些字符的输出用“?”表示 是否有一个简单的修复方法?确保没有意外丢失任何字节;一些UTF-8字符的长度超过一个字节(这是一个要点),您需要将它们全部保留下来 将缓冲区的内容打印为十六进制非常有用,因此您可以检查实际读取的字节: static void print_buffer(const char *buffer, size_t length) { siz
是否有一个简单的修复方法?确保没有意外丢失任何字节;一些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');
}
静态无效打印缓冲区(常量字符*缓冲区,大小\u t长度)
{
尺寸i;
对于(i=0;i
您可以在加载一个非常短的文件(仅包含几个字符)后执行此操作
还要确保终端设置为正确的编码,以便它将您的字符解释为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;
}
#包括
#包括
int main()
{
文件*f=fopen(“data.txt”,“r,ccs=UTF-8”);
如果(!f)
返回1;
for(wint_t c;(c=fgetwc(f))!=WEOF;)
printf(“%04X\n”,c);
fclose(f);
返回0;
}
链接
可能您的文本文件是ISO-8559-1编码的,但您的终端是UTF-8。在处理面向字节的文本处理时,这种不匹配是一个标准问题;其他C程序(如标准的“cat”和“more”命令)也会做同样的事情,一般不认为这是一个错误或需要修复的东西
如果您想在Unicode字符级别而不是字节级别上操作,这很好,但是您需要在整个程序中使用wchar作为字符类型而不是char,并为用户提供开关来指定传入文件编码的实际内容。(虽然有时可以猜测,但不太可靠。)我不知道这是否有帮助,但如果您确定终端和输入文件的编码相同,您可以尝试
设置语言环境()
:
#包括
…
setlocale(LC_CTYPE,“”);
My terminal设置为UTF-8编码。程序通过fgets()将文本文件中每行的所有字符存储到一个字符数组中;如果我丢失了字节,我不知道为什么或者如何修复它。。。(刚刚开始学习C btw)@Eirik,不要使用面向ASCII的fgets()。使用我帖子中的fgetwc()。没有问题。坚持下去,C中的Unicode并不是世界上最简单的东西。。。也要熟悉这些标准:)我使用了setlocale(LC_CTYPE,“UTF-8”)代码>。尽管正确配置了shell环境,但仍有必要成功读取文件。使用setlocale(LC_CTYPE,“”)
,应修改的区域设置的每个部分都是根据环境变量设置的。哦,是的,很抱歉,应该是”
,而不是NULL
。
#include <locale.h>
…
setlocale(LC_CTYPE, "");