/* 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> ", argv[0]); exit(1); } const char* FileName = argv[1]; if (-1 == _access(FileName, 0)) { printf("%s not exists! ", FileName); exit(1); } if (IsGbk(FileName)) { printf("%s is GBK Encoding. ", FileName); } else { printf("%s is not GBK Encoding. ", FileName); } return 0; }
经过更多的测试,发现上述代码有问题。
第一个问题,忽略了windows 文本文件中默认的 " " 对应的十六进制表示为 0D0A
第二个问题,GBK编码中对于英文字母仍然采用 ASCII 码的方式。
上述引用 http://www.cnblogs.com/tmscnz/archive/2012/12/12/2815339.html 不正确。
有图为证 (使用windows 自带的notepad穿件一个文本文件,采用winhex以 GBK格式打开,发现前8个字节为 ASCII码)