过滤4字节及以上的字符c++实现
这个是根据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++实现的更多相关文章
- Java bit、byte、位、字节、汉字、字符
package com.suypower.chengyu.test; public class ByteTest { /** * byte 8 bits -128 - + 127 * 1 bit = ...
- Java的IO操作中有面向字节(Byte)和面向字符(Character)两种方式
解析:Java的IO操作中有面向字节(Byte)和面向字符(Character)两种方式.面向字节的操作为以8位为单位对二进制的数据进行操作,对数据不进行转换,这些类都是InputStream和Out ...
- [19/03/30-星期六] IO技术_四大抽象类_ 字节流( 字节输入流 InputStream 、字符输出流 OutputStream )_(含字节文件缓冲流)
一.概念及分类 InputStream(输入流)/OutputStream(输出流)是所有字节输入输出流的父类 [注]输入流和输出流的是按程序运行所在的内存的角度划分的 字节流操作的数据单元是8的字节 ...
- java: InputStreamReader将字节的输入流变成字符的输入流,OutputStreamWriter将字符的输出流变成字节的输出流
InputStreamReader:将字节的输入流变成字符的输入流, OutputStreamWriter:将字符的输出流变成字节的输出流 //将缓冲区的内容读取,可以一次读取 //可以接收键盘的输入 ...
- Java字节缓冲流和字符缓冲流学习
1.字节缓冲流 首先要明确一个概念:对文件或其他目标频繁的读写操作,效率低,性能差. 使用缓冲流的好处是,能够高效的读写信息,原理是将数据先缓冲起来,然后一起写入或者读取出来. BufferedInp ...
- JAVA笔记11__File类/File类作业/字节输出流、输入流/字符输出流、输入流/文件复制/转换流
/** * File类:文件的创建.删除.重命名.得到路径.创建时间等,是唯一与文件本身有关的操作类 */ public class Main { public static void main(St ...
- 过滤3个字节以上的utf-8字符
/** * 过滤掉超过3个字节的UTF8字符 * @param text * @return * @throws UnsupportedEncodingException */ public stat ...
- python 过滤四字节字符 表情字符
项目中有时需要过滤掉四字节以上的字符(表情),比如mysql数据库5.5.3以下的版本text字段不支持四字节以上字符 于是就需要过滤掉再入库,python中的方法为: try: # pyth ...
- java中过滤四字节字符
private static final String FOUR_BYTE_FILTER = "[\\ud800\\udc00-\\udbff\\udfff\\ud800-\\udfff]& ...
随机推荐
- java SequenceInputStream类(序列输入流)的用法示例
public class SequenceInputStreamextends InputStream SequenceInputStream 表示其他输入流的逻辑串联.它从输入流的有序集合开始,并从 ...
- linux shutdown命令
shutdown [-t 秒] [-arkhncfF] 时间 [警告信息] 常用选项与参数: -t sec : -t 后面加秒数,亦即『过几秒后关机』的意思 -k : 不要真的关机,只是发送警告信息出 ...
- iOS-夜间模式(换肤设置)
概述 iOS 开发中有时候会有夜间模式(换肤设置)的需求, 主要是更改相关颜色操作每次切换夜间/白天模式时,都会发出通知给所有ViewController,让它们切换到相应的主题. 详细 代码下载:h ...
- ZooKeeper做独立server执行(上)
ZooKeeper做独立server执行(上) 作者:chszs.转载需注明.博客主页:http://blog.csdn.net/chszs 一.ZooKeeper安装及配置 版本号:ZooKeepe ...
- Android倒计时CountDownTimer小记
Android 超简便的倒计时实现: CountDownTimer CountDownTimer由系统提供 查资料的时候 发现了CountDownTimer这个类之后 果断抛弃了曾经的倒计时做法 功 ...
- maven内部运行原理解析(一)
来源于:http://www.jianshu.com/p/0fb5e3fb704d maven至今还是Java编程语言构建的事实标准,大部分项目还在使用maven来进行构建,因此了解maven内部运行 ...
- Git 清除远端已删除的分支
使用 git branch -a 命令可以查看所有本地分支和远程分支(git branch -r 可以只查看远程分支) 发现很多在远程仓库已经删除的分支在本地依然可以看到. # git branch ...
- Mysql 5.7 从节点配置多线程主从复制
Mysql 采用多线程进行复制是从 Mysql 5.6 开始支持的内容,但是 5.6 版本下有缺陷,虽然支持多线程,但是每个数据库只能一个线程,也就是说如果我们只有一个数据库,则主从复制时也只有一个线 ...
- springmvc最优化
java代码 package com.tgb.web.controller.annotation; import javax.servlet.http.HttpServletRequest; impo ...
- Android学习系列(9)--App列表之分组ListView
吸引用户的眼球,是我们至死不渝的追求: 第一时间呈现最有价值的信息,简明大方,告诉客户,你的选择是多么的明智,这正是你寻觅已久的东西. 分组的应用场合还是很多的,有数据集合的地方 ...