C++ UTF-8编码识别(分析文件内容,非文件头)

2023-11-05

UTF-8编码的文本文档,有的带有BOM (Byte Order Mark, 字节序标志),即0xEF, 0xBB, 0xBF,有的没有。Windows下的文本编辑器在保存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字符串也是有效的。

在程序中对最大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 - 1) 
                break; 
            if ((start[1] & (0xC0)) != 0x80) 
            { 
                IsUTF8 = false;
                 break;
            } 
            start += 2; 
        } 
        else if (*start < (0xF0)) // (11110000): 此范围内为3字节UTF-8字符 
        { 
            if (start >= end - 2) break;
            if ((start[1] & (0xC0)) != 0x80 || (start[2] & (0xC0)) != 0x80) 
            { 
                IsUTF8 = false; break; 
            } 
            start += 3; 
        } 
        else 
        { 
            IsUTF8 = false;
             break;
        }
    } 
    return IsUTF8; 
} 
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++ UTF-8编码识别(分析文件内容,非文件头) 的相关文章

随机推荐

  • canvas实现跟随鼠标和跟随手指粒子特效

    原文出处 https blog csdn net IForDreams article details 75453450 效果图 代码
  • TTL值的含义以及与域名DNS TTL值的区别

    什么是TTL TTL是IP协议包中的一个值 被称为跳数 指定数据报被路由器丢弃之前允许通过的网段数量 在很多情况下数据包在一定时间内不能被传递到目的地 解决方法就是在一段时间后丢弃这个包 然后给发送者一个报文 由发送者决定是否要重发 TTL
  • 【Python 1-8】Python手把手教程之——列表List的管理

    作者 弗拉德 来源 弗拉德 公众号 fulade me 在上一节我们学习了如何创建一个列表 在列表里面插入 删除数据等操作 本节我们学习如何管理列表 遍历列表 在日常开发中 我们经常需要遍历列表的所有元素 对每个元素执行相同的操作 例如 在
  • 什么是 Thread 的中断标志?

    分析 回答 什么是 Thread 的中断标志 中断 interrupt 标志或中断状态是线程中断时设置的内部线程标志 flag 属性 怎么设置中断标志 要设置一个线程的中断标志 只需要简单的在线程对象上调用 thread interrupt
  • radius服务器无响应,radius认证(radius认证超时)

    radius认证 RADIUS是英文 RemoteAuthenticationDialInUserService 的缩写 是网络远程接入设备的客户和包含用户认证与配置信息的服务器之间信息交换的标准客户 服务器模式 它包含有关用户的专门简档
  • Mac系统上配置Vue.js环境

    在Mac系统上配置Vue js环境非常麻烦 幸运地找到了教程http www mamicode com info detail 1786370 html 第一步 Mac OS系统安装 brew 在终端运行 usr bin ruby e cu
  • 纯CSS实现导航栏下拉动画效果

    实现思路 导航栏的下拉效果通过在ul的li里再嵌套一个ul 再通过animation属性改变第二导航栏ul的高度来实现导航栏下拉动画效果 老铁没毛病 实现效果 HTML代码 div class nav ul li a href 奥利给 a
  • PHP-代码执行函数-命令执行函数

    目录 代码执行函数 1 eval 函数 2 assert 函数 3 call user func 函数 4 create function 函数 5 array map 函数 6 call user func array 函数 7 arra
  • 哲理故事300篇(中)

    哲理故事300篇 上 http blog csdn net andylin02 archive 2006 08 23 1109314 aspx 哲理故事300篇 下 http blog csdn net andylin02 archive
  • LeetCode动态规划—跳跃游戏从跳到头到跳最少下跳到头(45、55)

    跳跃游戏 跳跃游戏 跳跃游戏 跳跃游戏 一个下标对应的值为3 那证明这个位置可以跳到前后3个位置的下标处 3均可达 如果依次遍历完这个数组 有下标在跳跃过程中最远位置仍然不可达 即证明无法到达最后一个位置 可以对每一个能作为 起跳点 的格子
  • 通讯录管理系统(C++)

    目录 1 功能分析与实现步骤 2 代码编写 2 1 联系人和通讯录结构体设计 2 2 通讯录页面 2 3 添加联系人 2 4 显示所有联系人 2 5 检测联系人 2 6 删除指定联系人 2 7 查找指定联系人 2 8 更改指定联系人 2 9
  • onu光功率多少是正常_发射光功率和接收灵敏度对光模块有什么影响

    我们在选购光模块需要留意发射光功率和接收灵敏度这两个参数 因为这两项参数是确保光模块正常通信关键因素之一 下面易天光通信 ETU LINK 就给大家介绍发射光功率和接收灵敏度分别是什么 以及如何测试光模块的光功率在正常范围呢 深圳易天光通信
  • python ssh登录偶然认证失败_paramiko.ssh_异常.AuthenticationException:身份验证失败

    import paramiko class SSHConnection object def init self host username password port 22 self sftp None self sftp open Fa
  • TypeScript--类型问题汇总

    学过js你认识的类型 boolean number string undefined null symbol object 你可能不认识的类型 void any unknown never 类型声明是TS非常重要的一个特点 通过类型声明可以
  • ORL Faces Database介绍

    ORL人脸数据集共包含40个不同人的400张图像 是在1992年4月至1994年4月期间由英国剑桥的Olivetti研究实验室创建 此数据集下包含40个目录 每个目录下有10张图像 每个目录表示一个不同的人 所有的图像是以PGM格式存储 灰
  • sql注入详解

    sql注入详解 SQLI介绍 SQLI sql injection 我们称之为sql注入 sql Structured Query Language 叫做结构化查询语句 在我们的应用系统使用 sql 语句进行管理应用数 据库时 往往采用拼接
  • AWS SAA-C03 #108

    A company has an automobile sales website that stores its listings in a database on Amazon RDS When an automobile is sol
  • 如何爬取淘宝电商数据

    在爬取淘宝电商数据之前 请务必遵守淘宝的相关规则和政策 并获得合法的授权 爬取淘宝数据的方法有很多种 这里介绍几种常见的方法 使用淘宝开放平台的 API 接口 淘宝开放平台提供了许多 API 接口 可以让开发者获取淘宝数据 使用 API 接
  • Github桌面端上传远程仓库以及将私有仓库改为公有仓库的方法

    1 桌面端上传远程仓库 pass 1 在github上下载一个桌面端应用程序 exe pass 2 用自己的github进行登录 可以在程序的头部栏看到一些应用操作 下载后登录了解即可 可以打开自己的github仓库 再打开本地文件夹 上传
  • C++ UTF-8编码识别(分析文件内容,非文件头)

    UTF 8编码的文本文档 有的带有BOM Byte Order Mark 字节序标志 即0xEF 0xBB 0xBF 有的没有 Windows下的文本编辑器在保存UTF 8格式的文本文档时会自动添加BOM到文件头 在判断这类文档时 可以根据