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

  1. #include <iostream>
  2. #include <string>
  3.  
  4. int strip4ByteChars(const std::string str, std::string &ot);
  5. unsigned char ord(int ch);
  6.  
  7. int main() {
  8. 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.";
  9. // std::string str = "abcdefg АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩъыьЭЮЯ 你好世界!";
  10. std::string ret;
  11. if( strip4ByteChars(str, ret) == ) {
  12. std::cout << str << std::endl << std::endl;
  13. std::cout << ret << std::endl;
  14. } else {
  15. std::cout << "error!" << std::endl;
  16. }
  17. return ;
  18. }
  19.  
  20. /**
  21. * 处理特殊字符串
  22. * @param string $str
  23. */
  24. int strip4ByteChars(const std::string str, std::string &ot) {
  25. int len = str.length();
  26. unsigned char v,v2,v3;
  27. for (int i = ; i < len; ) {
  28. v = ord(str[i]);
  29. if (v == 0x09 || v == 0x0A || (v < 0x80 && v >= 0x20)) { // 单字节
  30. ot += v;
  31. i += ;
  32. } else if (v >= 0xC2 && v <= 0xDF) { // 双字节
  33. v2 = ord(str[i + ]);
  34. if (v2 >= && v2 <= 0xBF) {
  35. ot += v;
  36. ot += v2;
  37. i += ;
  38. } else {
  39. ++i;
  40. }
  41. } else if (v == 0xE0) { // 三字节
  42. v2 = ord(str[i + ]);
  43. v3 = ord(str[i + ]);
  44. if (v2 >= 0xA0 && v2 <= 0xBF && v3 >= 0x80 && v3 <= 0xBF) {
  45. ot += v;
  46. ot += v2;
  47. ot += v3;
  48. i += ;
  49. } else {
  50. ++i;
  51. }
  52. } else if (v == 0xED) { // 三字节
  53. v2 = ord(str[i + ]);
  54. v3 = ord(str[i + ]);
  55. if (v2 >= 0x80 && v2 <= 0x9F && v3 >= 0x80 && v3 <= 0xBF) {
  56. ot += v;
  57. ot += v2;
  58. ot += v3;
  59. i += ;
  60. } else {
  61. i ++;
  62. }
  63. } else if (v >= 0xE1 && v <= 0xEF && v != 0xED) { // 三字节
  64. v2 = ord(str[i + ]);
  65. v3 = ord(str[i + ]);
  66. if (v2 >= 0x80 && v2 <= 0xBF && v3 >= 0x80 && v3 <= 0xBF) {
  67. ot += v;
  68. ot += v2;
  69. ot += v3;
  70. i += ;
  71. } else {
  72. i ++;
  73. }
  74. } else if (v >= 0xF1 && v <= 0xF4) { // 四字节
  75. i += ;
  76. } else { // 四字节以上
  77. i ++;
  78. }
  79. }
  80.  
  81. return ;
  82. }
  83. // 字符转ascii码,返回值为无符号int
  84. unsigned char ord(int ch) {
  85. unsigned char ret;
  86. ret = ch & 0xff;
  87. return ret;
  88. }

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

  1. Unicode符号范围 | UTF-8编码方式
  2. (十六进制) | (二进制)
  3. --------------------+---------------------------------------------
  4. 0000 0000-0000 007F | 0xxxxxxx
  5. 0000 0080-0000 07FF | 110xxxxx 10xxxxxx
  6. 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
  7. 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位,所以使用

  1. 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. 查询SQL存储过程创建时间

    select  [name] ,create_date ,modify_date FROM  sys.all_objects where  type_desc = N'SQL_STORED_PROCE ...

  2. demo02

    class PhoneNumber(): def __init__(self,number): self.a=number[1:4] self.b=number[6:9] self.c=number[ ...

  3. vsftp客户连接常见故障现象

    ftp客户连接常见故障现象现象0:> ftp: connect :连接被拒绝原因: 服务没启动解决: # chkconfig vsftpd on<Enter> 现象1:500 OOP ...

  4. 【云栖大会】阿里巴巴集团CTO张建锋:用计算和数据去改变整个世界

    摘要: 当浩瀚的数字化信息能够联网在线,在万物互联网的新世界中,所有东西都可能有感知.变智能,想象一下电表.冰箱.心电图监测仪等设备的信息都能数字化并联网,从城市管理到个人生活,都会迎来翻天覆地的变化 ...

  5. 简述Android触摸屏手势识别

    很多时候,利用触摸屏的Fling.Scroll等Gesture(手势)操作来操作会使得应用程序的用户体验大大提升,比如用Scroll手势在 浏览器中滚屏,用Fling在阅读器中翻页等.在Android ...

  6. RabbitMQ消息队列(五):Routing 消息路由 2[原]

    上一篇文章使用的是Direct的Exchange,但是没有指定Queue的名字,这样只能是先运行Consumer之后,Producer在运行发消息Consumer才能收到,否则先运行Producer发 ...

  7. PowerDesigner删除外键关系,而不删除外键列[转]

    PowerDesigner中配置外键关系时,如果要删除配置的外键关系,默认设置会一同删除外键列. 要更改此设置,需在菜单栏tools中打开Model Options,在Model Settings中点 ...

  8. 两个变量交换的四种方法(Java) 七种方法(JS)

    两个变量交换的四种方法(Java)   对于两种变量的交换,我发现四种方法,下面我用Java来演示一下. 1.利用第三个变量交换数值,简单的方法. (代码演示一下) 1 class TestEV 2 ...

  9. C#实现用Newtonsoft.Json 4.5.11解析人人网院校信息并获取院系信息

    http://cfanz.cn/index.php?c=article&a=read&id=42444 http://files.cnblogs.com/lyl6796910/Wind ...

  10. Interface_GL通过gl_interface导入日记账(案例)

    2014-06-17 BaoXinjian