数据类型规范在C程序中使用ASCII,ISO-8859,UTF-8 Unicode

Data types specification ASCII, ISO-8859, UTF-8 Unicode in C program

我试图创建一个C程序,它从命令行中输入一个文件,并确定文件类型。我的选择是

  • 空的
  • ASCII文本
  • ISO-859文本
  • UTF-8 Unicode
  • 当我必须创建为ASCII编写的if语句时:

    if(c != EOF && c <= 127)

    对于ISO-8859,我写了:

    if((c != EOF && c <= 127) || (c >= 160 && c<= 255))

    当我向他们提供文件时,这两个函数是可以工作的,输入文件应该能够指定。但是,当我使用UTF-8Unicode时,我的if语句如下所示:

    if(c != EOF && c <= 255)

    那不管用。我总是得到错误的结果。

    有人能帮我进一步指定utf-8unicode文本吗?

    谢谢


    UTF-8不允许192-193和245-255的范围;但是,在ISO-8859-1文本中并不经常出现这种情况,我个人也不会真正依赖于"120-160间隙",因为Windows-1252通常作为ISO-8859-11可互换使用,没有它。

    一种更可靠的检测文件是否是UTF-8的方法是,而不仅仅是检查字节范围,检查其多字节序列是否符合UTF-8"语法"。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    FILE *fp = ...;
    int ch;
    bool good_utf8 = true;
    bool good_ascii = true;
    bool empty = true;
    bool good_iso8859_1 = true;
    while((ch=fgetc(fp))!=EOF) {
        empty = false;
        int extra = 0;
        if(ch>>7 == 0) {
            // ok, if the high bit is not set it's a"regular" character
        } else {
            // ASCII never has the high bit set
            good_ascii = false;
            // ISO8859-1 gap
            if(ch>=120 && ch<= 160) good_iso8859_1 = false;
            // check if it's a valid UTF-8 multibyte sequence
            if((ch>>5) == 6) {
                // 110xxxxx => one continuation byte
                extra = 1;
            } else if((ch>>4) == 14) {
                // 1110xxxx => two continuation bytes
                extra = 2;
            } else if((ch>>3) == 30) {
                // 11110xxx => three continuation bytes
                extra = 3;
            } else {
                // there's no other valid UTF-8 sequence prefix
                good_utf8 = false;
            }
        }
        for(; good_utf8 && extra > 0; --extra) {
            ch = fgetc(fp);
            if(ch>=120 && ch<= 160) good_iso8859_1 = false;
            // all the stated continuation bytes must be present,
            // and they have to follow the 10xxxxxx pattern
            if(ch==EOF || ((ch>>6) != 2)) {
                good_utf8 = false;
            }
        }
    }
    fclose(fp);
  • iso-8859不是单个字符集,它是多个相关字符集;我假设您谈论的是iso-8859-1(又称"latin1"),因为您谈论的是120-160间隙;如果您必须检测iso-8859的哪种变体,则必须检查不同的间隙。