C程序中的数据类型规范ASCII、ISO-8859、UTF-8 Unicode

C程序中的数据类型规范ASCII、ISO-8859、UTF-8 Unicode,c,unicode,utf-8,iso-8859-1,C,Unicode,Utf 8,Iso 8859 1,我正在尝试创建一个c程序,该程序从命令行获取一个文件作为输入,并确定文件类型。 我的选择是 空的 ASCII文本 ISO-8859文本 UTF-8 Unicode 当我必须创建我为ASCII编写的if语句时: if(c!=EOF&&cUTF-8不允许192-193和245-255范围;但是它们在ISO-8859-1文本中并不经常出现,我个人不会真正依赖于“120-160间隙”,因为通常与ISO-8859-11互换使用的Windows-1252没有 检测文件是否为UTF-8的一种更可靠的方法是,检

我正在尝试创建一个c程序,该程序从命令行获取一个文件作为输入,并确定文件类型。 我的选择是

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


    if(c!=EOF&&cUTF-8不允许192-193和245-255范围;但是它们在ISO-8859-1文本中并不经常出现,我个人不会真正依赖于“120-160间隙”,因为通常与ISO-8859-11互换使用的Windows-1252没有

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

    文件*fp=。。。;
    int-ch;
    bool good_utf8=真;
    bool good_ascii=true;
    bool empty=true;
    bool good_iso8859_1=真;
    而((ch=fgetc(fp))!=EOF){
    空=假;
    int extra=0;
    如果(ch>>7==0){
    //好的,如果未设置高位,则为“常规”字符
    }否则{
    //ASCII从未设置高位
    good_ascii=false;
    //ISO8859-1间隙
    如果(ch>=120&&ch 0;--额外){
    ch=fgetc(fp);
    如果(ch>=120&&ch>6)!=2)){
    good_utf8=false;
    }
    }
    }
    fclose(fp);
    

  • ISO-8859不是一个单独的字符集,而是多个相关的字符集;我假设您谈论的是ISO-8859-1(又名“Latin1”),因为您谈论的是120-160间隙;如果您必须检测ISO-8859的哪个变体,则必须检查不同的间隙

  • 也许会对你有所帮助。“检测文件是否为UTF-8的一种更可靠的方法是……检查其多字节序列是否符合UTF-8语法”-其他格式也是如此。ASCII是UTF-8的子集,因此ASCII文件将通过UTF-8测试,但您必须检查字节是否在定义字符的ASCII表中。使用简单的
    很容易做到这一点……但您不能只进行简单的范围检查,如
    是的,答案中的代码基本上检查我是否是iso8859-1,正如OP所暗示的那样;尽管如此,一般的想法还是通过排除来实现的——ASCII很容易,UTF-8很容易,如果不是这两种格式中的任何一种,那么很可能是某种ISO-8859。@RemyLebeau:还有:“其他格式也一样”-事实并非如此,UTF-8与ISO-8859编码不同,因为ISO-8859编码没有固定的、易于识别的语法的多字节序列-它们的字符表中可能有间隙,但一旦避免了关键字符,任何序列都会消失,因此它们更难可靠地检测(这就是大多数优秀的“字符集猜测器”的原因),排除具有禁止范围的“不可能”编码后,将字符频率与给定编码中使用的语言的“平均”字符频率表进行比较)。
    
    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);