24-IO流-70-IO流(练习-按字节截取字符串)
2015-08-11 16:41
253 查看
/* * 【练习】 * 在java中,字符串“abcd”与字符串“ab你好”的长度是一样,都是4个字符,但对应的字节数不同,一个汉字=2字节,一个字母= * 1字节。 * * 定义一个方法,按照最大的字节数来取字符串。 * * 如:对于“ab你好”,如果取3个字节,那么子串就是ab与“你”字的半个,那么这半个“你”字就要舍弃(因为如果显示是有问题的 * )。如果取4个字节就是“ab你”,取5个字节还是“ab你”(5个字节=ab你+“好”字半边,为了显示正常,舍弃“好”字半边)。 */ /** * 【思路】 * “ab你好”对应的GBK编码是:97 98 -60 -29 -70 -61, * 设取x字节,那么直接取出从0到x字节的子串,获取最后一个编码(对应编号是x-1,设取5个字节,直接拿最后一个字节-70,对应 * 编号为4),之后判断最后一个编码是否为负数,是负数说明当前编码是汉字的编码,不是说明是字母的编码,若不是负数,直接将 * 0到x的子串打印输出即可;若是负数,从该编码位置从后往前依次判断每一个编码是否为负数,最终看负数编码的个数,若为奇数, * 则舍弃最后一个编码(因为1汉字=2字节,奇数说明最后一个编码对应某一汉字的一半),若为偶数,直接打印输出。 */ package test; import java.io.UnsupportedEncodingException; public class IOTest { public static void main(String[] args) throws UnsupportedEncodingException { String str = "ab你好"; int len = str.getBytes("GBK").length;//获取str用GBK编码的长度 for(int x = 1; x<len;x++){ System.out.println("截取"+x+"个字节结果是:"+cutStringByByte(str, x)); } } public static String cutStringByByte(String str, int len) throws UnsupportedEncodingException{ //参数str是原字符串,参数len是从原字符串中所要截取的字节数 //将字符串str变成字节数组 byte[] buf = str.getBytes("GBK"); int count = 0;//计数器,用于计算str内汉字的个数 for(int x = len-1; x>0 ; x--){ if(buf[x]<0)//如果当前位置编码为负数,说明是中文,计数器自增 count++; else//否则是英文,直接跳出循环 break; } //如果有偶数个汉字,直接将buf全部解码,如果有奇数个汉字,舍弃最后一个编码,将剩余解码 if(count%2==0) return new String(buf,0,len,"GBK"); else return new String(buf,0,len-1,"GBK"); } } /* * 【运行结果】 * 截取1个字节结果是:a * 截取2个字节结果是:ab * 截取3个字节结果是:ab * 截取4个字节结果是:ab你 * 截取5个字节结果是:ab你 */
=============================分割线=============================
//前面是用GBK验证的,这里用UTF-8验证 package test; import java.io.UnsupportedEncodingException; public class IOTest2 { public static void main(String[] args) throws UnsupportedEncodingException { String str = "ab你好"; int len = str.getBytes("UTF-8").length; for(int x = 1;x<len;x++){ System.out.println("截取"+x+"个字节的结果是:"+cutStringByU8Byte(str,x)); } } public static String cutStringByU8Byte(String str, int len) throws UnsupportedEncodingException { byte[] buf = str.getBytes("UTF-8"); int count=0; for(int x=len-1;x<len;x--){ if(buf[x]<0) count++; else break; } if(count%3==0)//UTF-8码表一个汉字占3个字节,所以这里count%3,其结果只有三种可能:0、1、2 return new String(buf,0,len,"UTF-8");//若count%3==0,说明所要截取的len个字节,最后正好是完整的汉字 else if(count%3==1) return new String(buf,0,len-1,"UTF-8");//若count%3==1,说明最后是1/3个汉字,直接舍弃 else return new String(buf,0,len-2,"UTF-8");//若count%3==2,说明最后是2/3个汉字,直接舍弃 } } /* * 【运行结果】 * 截取1个字节的结果是:a * 截取2个字节的结果是:ab * 截取3个字节的结果是:ab * 截取4个字节的结果是:ab * 截取5个字节的结果是:ab你 * 截取6个字节的结果是:ab你 * 截取7个字节的结果是:ab你 */
相关文章推荐
- linux 同步IO: sync、fsync与fdatasync
- 静态变量的初始化
- 一行命令 优化上传速度
- 礼物
- 从错误中学python(1) —— 规范化英文名字
- js正则
- 耗子学Python了(2)__Python开发“Hello World”
- 在Python中数据类型转换的注意事项
- 自定义不等高的cell
- Android如何获取当前应用版本号?
- 【面试笔试-c/c++】2012年9月土豆优酷网校园招聘笔试
- 【面试笔试-c/c++】兰亭集势2013校园招聘试题。
- [HDU 4081] Qin Shi Huang's National Road System 最小树
- php对象赋值
- 24-IO流-69-IO流(联通问题)
- redis主从配置及主从切换
- HDU 1241 Oil Deposits
- 自定义等高的cell
- vim文件加解密
- Autolayout