c读取非ASCII字符

beo*_*ver 5 c text character-encoding non-ascii-characters

我解析,涉及到的字符,如文件æ ø å.如果我们假设我已经存储了一行文本文件,如下所示

#define MAXLINESIZE 1024
char* buffer = malloc(MAXLINESIZE)
...
fgets(buffer,MAXLINESIZE,handle)
...
Run Code Online (Sandbox Code Playgroud)

如果我想计算一行中的字符数.如果我尝试执行以下操作:

char* p = buffer
int count = 0;
while (*p != '\n') {
    if (isgraph(*p)) {
        count++;
    }
    p++;
}
Run Code Online (Sandbox Code Playgroud)

这忽略了任何的发生æ ø å

即:计算"aåeæioøu"将返回5而不是8

我是否需要以另一种方式阅读文件?我不应该使用char*但是int*

Bas*_*tch 2

您需要了解您的字符使用哪种编码。我猜它很可能是UTF-8(你应该在任何地方都使用 UTF8 ....),请阅读Joel 关于 Unicode 的博客。如果您的编码不是 UTF-8,您应该将其转换为 UTF-8,例如使用libiconv

那么您需要一个用于 UTF-8 的 C 库。其中有很多(但尚未在C11语言中标准化)。我推荐libunistringglib(来自 GTK),但另请参阅this

您的代码将会改变,因为 UTF-8 字符可以占用一到四个 [8 位] 字节(但维基百科UTF-8页面最多提到 6 个字节;有关详细信息,请参阅Unicode标准)。您不会测试一个字节(即普通的 C char)是否是一个字母,但如果一个字节及其后面的几个字节(由指针给出,即 achar*或更好地由给出uint8_t*)编码一个字母(包括西里尔字母等)。 .)。

并非每个字节序列都是有效的 UTF-8 表示形式,您可能需要在分析一行(或以 null 结尾的 C 字符串)之前对其进行验证。

  • 无论旧文档如何建议,在 UTF-8 中表示 Unicode 代码点所需的最大字节数是 4。最后一个 Unicode 值是 U+10FFFF。十年或更久以前,上限还没有定义。 (2认同)