繁体   English   中英

c读取非ASCII字符

[英]c reading non ASCII characters

我解析,涉及人物如AE o 一个文件。 如果我们假设我已经存储了一行文本文件,如下所示

#define MAXLINESIZE 1024
char* buffer = malloc(MAXLINESIZE)
...
fgets(buffer,MAXLINESIZE,handle)
...

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

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

这忽略的æ○的任何事件

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

我是否需要以其他方式读取文件? 我应该使用char*而不是int*吗?

C标准IO库只能读取字节 您的文件可能包含用UTF8或其他某种编码编码的多字节字符。 您将需要一个库来解释此类文件。

您的文件可能包含Latin1文本,在这种情况下,字符为字节。 在这种情况下,除非具有正确的语言环境设置,否则不能使用isgraph

底线:找到文件中使用的编码。 然后据此阅读。 无论如何,普通C都不知道编码。

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

然后,您需要一个用于UTF-8的C库。 其中有很多(但C11语言尚未标准化)。 我建议使用libunistringglib (来自GTK),但也请参阅this

您的代码将更改,因为UTF-8字符可能占用一到四个[8位]字节(但Wikipedia UTF-8页最多提及6个字节;有关详细信息,请参见Unicode标准)。 您不会测试一个字节(即纯C char )是否为字母,但是如果一个字节及其后的几个字节(由指针赋予,即char*或由uint8_t*赋予更好)编码一个字母(包括西里尔字母等。)。

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

假设您使用UTF-8。

您需要了解UTF-8的工作原理

这是您应该做的一小部分工作:

int nbChars(char *str) {
    int len = 0;
    int i = 0;
    int charSize = 0; // Size of the current char in byte

    if (!str)
        return -1;
    while (str[i])
    {
        if (charSize == 0)
        {
            ++len;
            if (!(str[i] >> 7 & 1)) // ascii char
                charSize = 1;
            else if (!(str[i] >> 5 & 1))
                charSize = 2;
            else if (!(str[i] >> 4 & 1))
                charSize = 3;
            else if (!(str[i] >> 3 & 1))
                charSize = 4;
            else
                return -1; // not supposed to happen
        }
        else if (str[i] >> 6 & 3 != 2)
            return -1;
        --charSize;
        ++i;
    }
    return len;
}

它返回字符数,如果不是有效的UTF-8字符串,则返回-1。

(通过无效的UTF-8字符串,我的意思是格式无效。我不检查字符是否确实存在)

编辑:如注释部分所述,此代码不处理分解的unicode

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM