转自:http://blog.csdn.net/jiangqin115/article/details/42684017

UTF-8编码的文本文档,有的带有BOM (Byte Order Mark, 字节序标志),即0xEF, 0xBB, 0xBF,有的没有。Windows下的txt文本编辑器在保存UTF-8格式的文本文档时会自动添加BOM到文件头。在判断这类文档时,可以根据文档的前3个字节来进行判断。然而BOM不是必需的,而且也不是推荐的。对不希望UTF-8文档带有BOM的程序会带来兼容性问题,例如Java编译器在编译带有BOM的UTF-8源文件时就会出错。而且BOM去掉了UTF-8一个期望的特性,即是在文本全部是ASCII字符时UTF-8是和ASCII一致的,即UTF-8向下兼容ASCII。

在具体判断时,如果文档不带有BOM,就无法根据BOM做出判断,而且IsTextUnicode API也无法对UTF-8编码的Unicode字符串做出判断。那在编程判断时就要根据UTF-8字符编码的规律进行判断了。

UTF-8是一种多字节编码的字符集,表示一个Unicode字符时,它可以是1个至多个字节,在表示上有规律:

1字节:0xxxxxxx
2字节:110xxxxx 10xxxxxx
3字节:1110xxxx 10xxxxxx 10xxxxxx
4字节:11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

这样就可以根据上面的特征对字符串进行遍历来判断一个字符串是不是UTF-8编码了。应该指出的是UTF-8字符串的各个字节的取值有一定的范围,并不是所有的值都是有效的UTF-8字符,但是一般的应用的情况下这样的判断在对足够长的字符串及是比较精确了,而且实现也比较简单。具体的字节取值范围可以参见"Unicode Explained"一书中的6.4.3。另外BOM本身也符合3字节UTF-8字符编码规律,所以本方法对带BOM的UTF-8字符串也是有效的。

1. 判断文本是否UTF编码

在下面程序中对最大3字节长的UTF-8字符进行了判断,在实际情况下,几乎所有能用到的UTF-8字符最长就是3个字节

 bool IsUTF8(const void* pBuffer, long size)
{
bool IsUTF8 = true;
unsigned char* start = (unsigned char*)pBuffer;
unsigned char* end = (unsigned char*)pBuffer + size;
while (start < end)
{
if (*start < 0x80) // (10000000): 值小于0x80的为ASCII字符
{
start++;
}
else if (*start < (0xC0)) // (11000000): 值介于0x80与0xC0之间的为无效UTF-8字符
{
IsUTF8 = false;
break;
}
else if (*start < (0xE0)) // (11100000): 此范围内为2字节UTF-8字符
{
if (start >= end - )
{
break;
} if ((start[] & (0xC0)) != 0x80)
{
IsUTF8 = false;
break;
} start += ;
}
else if (*start < (0xF0)) // (11110000): 此范围内为3字节UTF-8字符
{
if (start >= end - )
{
break;
} if ((start[] & (0xC0)) != 0x80 || (start[] & (0xC0)) != 0x80)
{
IsUTF8 = false;
break;
} start += ;
}
else
{
IsUTF8 = false;
break;
}
} return IsUTF8;
}

2. 判断文件是否UTF-8编码:

 bool CConvertCharset::IsUTF8File(const char* pFileName)
{
FILE *f = NULL;
fopen_s(&f, pFileName, "rb");
if (NULL == f)
{
return false;
} fseek(f, , SEEK_END);
long lSize = ftell(f);
fseek(f, , SEEK_SET); //或rewind(f); char *pBuff = new char[lSize + ];
memset(pBuff, , lSize + );
fread(pBuff, lSize, , f);
fclose(f); bool bIsUTF8 = IsUTF8Text(pBuff, lSize);
delete []pBuff;
pBuff = NULL; return bIsUTF8;
}

最新文章

  1. ASP.NET Core 中文文档 第二章 指南(5) 在 Nano Server 上运行ASP.NET Core
  2. 5. UIView
  3. WebWorker的importScripts方法
  4. Python isdigit()方法
  5. Python: 拷贝函数签名
  6. twitter storm源码走读之6 -- Trident Topology执行过程分析
  7. php扩展的基本安装
  8. C语言的指针
  9. Hadoop2.6.0 动态增加节点
  10. Kubernetes运维生态-Heapster分析
  11. One day one cf,Keep Wa away from me.
  12. 01_数据库连接池,数据源,ResultSetMetaData,jdbc优化
  13. 插件前奏-android黑科技 hook介绍
  14. 关于jstl中碰到的Property &#39;username&#39; not found on type java.lang.String异常
  15. 「九省联考 2018」IIIDX 解题报告
  16. Java并发编程-信号量
  17. linux命令:文件搜索命令
  18. java抽象类,接口与异常
  19. cgic程序的编写遇到的问题
  20. PHP递归无限分类,数组和直接输出。

热门文章

  1. RabbitMQ错误检查
  2. 四、redis系列之主从复制与哨兵机制
  3. 文件系统层级结构标准(FHS)
  4. &lt;泛&gt; STL - stack 模拟实现
  5. sql find duplicate
  6. 机器学习之路:python 特征降维 特征筛选 feature_selection
  7. luoguP4491 [HAOI2018]染色 广义容斥原理 + FFT
  8. 处理QMenu的triggered信号时遇到的一个问题
  9. hdu 1518 dfs+剪枝
  10. Vue 生命周期方法