这个是根据php的一个版本改的,用来处理utf-8编码的多字节字符,比如中文,俄文等等。

#include <iostream>
#include <string> int strip4ByteChars(const std::string str, std::string &ot);
unsigned char ord(int ch); int main() {
std::string str = "Esto es una prueba lalalala así que la llenaré de ÑÑÑÑÑÑ así y también de ÇÇÇÇÇÇÇÇ y algunos acentos en francés del tipo télévision, évenement, ouvrière, même, hôpital, juïf o âge.";
// std::string str = "abcdefg АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩъыьЭЮЯ 你好世界!";
std::string ret;
if( strip4ByteChars(str, ret) == ) {
std::cout << str << std::endl << std::endl;
std::cout << ret << std::endl;
} else {
std::cout << "error!" << std::endl;
}
return ;
} /**
* 处理特殊字符串
* @param string $str
*/
int strip4ByteChars(const std::string str, std::string &ot) {
int len = str.length();
unsigned char v,v2,v3;
for (int i = ; i < len; ) {
v = ord(str[i]);
if (v == 0x09 || v == 0x0A || (v < 0x80 && v >= 0x20)) { // 单字节
ot += v;
i += ;
} else if (v >= 0xC2 && v <= 0xDF) { // 双字节
v2 = ord(str[i + ]);
if (v2 >= && v2 <= 0xBF) {
ot += v;
ot += v2;
i += ;
} else {
++i;
}
} else if (v == 0xE0) { // 三字节
v2 = ord(str[i + ]);
v3 = ord(str[i + ]);
if (v2 >= 0xA0 && v2 <= 0xBF && v3 >= 0x80 && v3 <= 0xBF) {
ot += v;
ot += v2;
ot += v3;
i += ;
} else {
++i;
}
} else if (v == 0xED) { // 三字节
v2 = ord(str[i + ]);
v3 = ord(str[i + ]);
if (v2 >= 0x80 && v2 <= 0x9F && v3 >= 0x80 && v3 <= 0xBF) {
ot += v;
ot += v2;
ot += v3;
i += ;
} else {
i ++;
}
} else if (v >= 0xE1 && v <= 0xEF && v != 0xED) { // 三字节
v2 = ord(str[i + ]);
v3 = ord(str[i + ]);
if (v2 >= 0x80 && v2 <= 0xBF && v3 >= 0x80 && v3 <= 0xBF) {
ot += v;
ot += v2;
ot += v3;
i += ;
} else {
i ++;
}
} else if (v >= 0xF1 && v <= 0xF4) { // 四字节
i += ;
} else { // 四字节以上
i ++;
}
} return ;
}
// 字符转ascii码,返回值为无符号int
unsigned char ord(int ch) {
unsigned char ret;
ret = ch & 0xff;
return ret;
}

多字节字符的二进制表示如下:

Unicode符号范围      | UTF-8编码方式
(十六进制) | (二进制)
--------------------+---------------------------------------------
0000 0000-0000 007F | 0xxxxxxx
0000 0080-0000 07FF | 110xxxxx 10xxxxxx
0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

以双字节字符为例110xxxxx 10xxxxxx

使用下标访问时每次访问一个字节,这时候双字节字符会被分开访问,如上的双字节将会分为110xxxxx和10xxxxxx,使用int保存时,单字节会自动补齐为当前系统中int需要的字节数,补齐规则跟系统有关,带符号数通常是按照符号位的值补齐,由于这两个字节的最高位都是1,以int为4字节为例,这两个字节在实际访问时就会变成:

11111111 11111111 11111111 110xxxxx 和 11111111 11111111 11111111 10xxxxxx

这样如果直接使用这两个值就会得到一个负数,而且远远超出了ascii码的表示范围,而我们真正需要的只是这两个int的地8位,所以使用

ret = ch & 0xff;

取出低8位,又因为ascii码没有负数,所以应该用unsigned char表示。

参考文件:http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html

过滤4字节及以上的字符c++实现的更多相关文章

  1. Java bit、byte、位、字节、汉字、字符

    package com.suypower.chengyu.test; public class ByteTest { /** * byte 8 bits -128 - + 127 * 1 bit = ...

  2. Java的IO操作中有面向字节(Byte)和面向字符(Character)两种方式

    解析:Java的IO操作中有面向字节(Byte)和面向字符(Character)两种方式.面向字节的操作为以8位为单位对二进制的数据进行操作,对数据不进行转换,这些类都是InputStream和Out ...

  3. [19/03/30-星期六] IO技术_四大抽象类_ 字节流( 字节输入流 InputStream 、字符输出流 OutputStream )_(含字节文件缓冲流)

    一.概念及分类 InputStream(输入流)/OutputStream(输出流)是所有字节输入输出流的父类 [注]输入流和输出流的是按程序运行所在的内存的角度划分的 字节流操作的数据单元是8的字节 ...

  4. java: InputStreamReader将字节的输入流变成字符的输入流,OutputStreamWriter将字符的输出流变成字节的输出流

    InputStreamReader:将字节的输入流变成字符的输入流, OutputStreamWriter:将字符的输出流变成字节的输出流 //将缓冲区的内容读取,可以一次读取 //可以接收键盘的输入 ...

  5. Java字节缓冲流和字符缓冲流学习

    1.字节缓冲流 首先要明确一个概念:对文件或其他目标频繁的读写操作,效率低,性能差. 使用缓冲流的好处是,能够高效的读写信息,原理是将数据先缓冲起来,然后一起写入或者读取出来. BufferedInp ...

  6. JAVA笔记11__File类/File类作业/字节输出流、输入流/字符输出流、输入流/文件复制/转换流

    /** * File类:文件的创建.删除.重命名.得到路径.创建时间等,是唯一与文件本身有关的操作类 */ public class Main { public static void main(St ...

  7. 过滤3个字节以上的utf-8字符

    /** * 过滤掉超过3个字节的UTF8字符 * @param text * @return * @throws UnsupportedEncodingException */ public stat ...

  8. python 过滤四字节字符 表情字符

    项目中有时需要过滤掉四字节以上的字符(表情),比如mysql数据库5.5.3以下的版本text字段不支持四字节以上字符 于是就需要过滤掉再入库,python中的方法为:   try:   # pyth ...

  9. java中过滤四字节字符

    private static final String FOUR_BYTE_FILTER = "[\\ud800\\udc00-\\udbff\\udfff\\ud800-\\udfff]& ...

随机推荐

  1. Ubuntu解压缩zip,tar,tar.gz,tar.bz2

    ZIP zip可能是目前使用得最多的文档压缩格式.它最大的优点就是在不同的操作系统平台,比如Linux, Windows以及Mac OS,上使用.缺点就是支持的压缩率不是很高,而tar.gz和tar. ...

  2. python学习笔记之基础数据和控制

    注释: 单行注释 # 多行注释'''    ''' 注意:当注释中有汉字时需要在python文件的第一行添加如下内容之一:#coding:gbk或#coding:utf-8或##-*- coding ...

  3. 用 Qt Creator 开发非 Qt 的 C/C++ 程序

    在Windows还是习惯用VS2005但是现在到了Linux下,开发起来C/C++程序就没有那么得心应手的IDE了.虽然很多人推荐E开头那个主要作为Java开发的IDE,不过安上插件后感觉不大好,一个 ...

  4. JavaScript的技巧和最佳实践

    JavaScript是一个绝冠全球的编程语言,可用于Web开发.移动应用开发(PhoneGap.Appcelerator).服务器端开发 (Node.js和Wakanda)等等.JavaScript还 ...

  5. Python接通图灵机器人

    图灵机器人 图灵机器人特别low,问答水平并不高. import requests print("你好,我是图灵机器人") while 1: s = input() resp = ...

  6. 工作总结 ModelState.AddModelError("ShiYiObject", "对象不能为空!"); 小知识

    // // 摘要: // 获取包含模型状态和模型绑定验证状态的模型状态字典对象. // // 返回结果: // 模型状态字典. public ModelStateDictionary ModelSta ...

  7. Android:GridView中实现点击Item变色,再点击还原。

    使用GridView时想实现点击其中的一个Item,该Item改变背景,再次点击Item变回原来的背景,网上搜了很多资料都没有看到类似的案例,但还是有所启发,现来分享我的做法. 首先,首先为GridV ...

  8. activity的onCreate参数 saveInstanceState

        写过Android程序的都知道Activity中有一个名称叫onCreate的方法.该方法是在Activity创建时被系统调用,是一个Activity生命周期的开始.可是有一点容易被忽视,就是 ...

  9. 关于apache服务器加载so的报错

    早上突然发现我的虚拟机上的WEB应用访问不了了,后台检查httpd服务,无法启动,出现一行提示: ①starting httpd: httpd: Syntax error on line 163 of ...

  10. .NET设计模式(4):建造者模式(Builder Pattern)(转载)

    概述 在 软件系统中,有时候面临着“一个复杂对象”的创建工作,其通常由各个部分的子对象用一定的算法构成:由于需求的变化,这个复杂对象的各个部分经常面临着剧 烈的变化,但是将它们组合在一起的算法确相对稳 ...