检测一个文本文件的编码是否为GBK

/*
    Time:   2016年12月9日16:00:40
    Author: Albert Wang
    email:  albertofwb@gmail.com
    Function: detect whether a text file's encoding is GBK format
*/

/*
    参考连接: http://www.cnblogs.com/tmscnz/archive/2012/12/12/2815339.html

    GBK是国家标准GB2312基础上扩容后兼容GB2312的标准。GBK的文字编码是用双字节来表示的,
    即不论中、英文字符均使用双字节来表示,为了区分中文,将其最高位都设定成1。
    GBK包含全部中文字符,是国家编码,通用性比UTF8差,不过UTF8占用的数据库比GBK大。
*/

#include <stdio.h>
#include <stdlib.h>  // exit()
#include <direct.h>  // _access() detect a file's existence
#include <iostream>  // true, false defination

int DumpFromFile(const char *FileName, char *buf, size_t FileSize)
{
    FILE     *fp;

    if ((fp = fopen(FileName, "rb")) == NULL)
    {
        return -1;
    }
    fread(buf, 1, FileSize, fp);

    fclose(fp);

    return 0;
}


int GetFileSize(const char *FileName, size_t *FileSize)
{
    FILE *fp;

    if ((fp = fopen(FileName, "rb")) == NULL)
    {
        //perror(FileName);  //调试,显示具体出错信息
        return -1;
    }
    fseek(fp, 0, SEEK_END);
    *FileSize = ftell(fp);

    fclose(fp);
    fp = NULL;

    return 0;
}

bool IsGbk(const char* FileName)
{
    FILE *fp = NULL;
    size_t FileSize = 0;
    char *fileBuf = NULL;


    GetFileSize(FileName, &FileSize);
    fileBuf = (char *)malloc(FileSize);
    DumpFromFile(FileName, fileBuf, FileSize);

    size_t i = 0;
    bool ret = true;

    for ( ; i < FileSize; i++)
    {
        if ( ! (0x80 & fileBuf[i]) )
        {
            ret = false;
            break;
        }
    }


    free(fileBuf);
    return ret;
}

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        printf("Usage: %s <FileName>\n", argv[0]);
        exit(1);
    }

    const char* FileName = argv[1];
    if (-1 == _access(FileName, 0))
    {
        printf("%s not exists!\n", FileName);
        exit(1);
    }

    if (IsGbk(FileName))
    {
        printf("%s is GBK Encoding.\n", FileName);
    }
    else
    {
        printf("%s is not GBK Encoding.\n", FileName);
    }

    return 0;
}

 经过更多的测试,发现上述代码有问题。

   第一个问题,忽略了windows 文本文件中默认的 "\r\n" 对应的十六进制表示为 0D0A

   第二个问题,GBK编码中对于英文字母仍然采用 ASCII 码的方式。

  上述引用 http://www.cnblogs.com/tmscnz/archive/2012/12/12/2815339.html 不正确。

有图为证 (使用windows 自带的notepad穿件一个文本文件,采用winhex以 GBK格式打开,发现前8个字节为 ASCII码)


posted @ 2016-12-09 16:10  SurfUniverse  阅读(2533)  评论(0编辑  收藏  举报