黑马程序员技术交流社区
标题: GBK码相关问题,求大神的指导 [打印本页]
作者: 郭珍 时间: 2014-4-13 22:31
标题: GBK码相关问题,求大神的指导
编写函数,从一个字符串中按字节数截取一部分,但不能截取出半个中文(GBK码表)
例如:从“HM程序员”中截取2个字节是“HM”,截取4个则是“HM程”,截取3个字节也要是"HM"而不要出现半个中文
作者: ___________゛M 时间: 2014-4-14 08:32
可以用String类的substring方法,输入截取的位置就可以截取到相应位置的字符串。
- public static String getStr(int n,String str)
- {
- return str.substring(0, n);
- }
-
- public static void main(String[] args) {
- System.out.println(getStr(3,"HM程序员"));
- }
复制代码
作者: 张治国 时间: 2014-4-14 08:48
关键的代码,分享一下
//自定义截取函数
public static String MySubString(String s , int n) {
//转换成字节数组
byte[] buf = s.getBytes();
int num = 0;
//定义标记
boolean flag = false;
for (int i = 0; i < n; i++) {
if (buf[i] < 0 && !flag) {
flag = true;
} else {
num++;
flag = false;
}
}
return s.substring(0,num);
}
作者: alucard 时间: 2014-4-14 10:35
- /*
- 题目:
- 从“HM程序员训练营”中截取2个字节是“HM”,截取4个则是“HM程”,截取3个字节也要是"HM"而不要出现半个中文。
- 分析:
- 题目的要求是从字符串中按字节数截取,所以字符串转换为字节数组是肯定的,字母还好说,就占一个字节,
- 问题的关键在于字符串中有汉字的出现,GBK编码中汉字字符是占两个字节的,两个字节分开无法识别,
- 当截取的字节数最后一位是代表半个字符的字节时,运行结果中的字符串末尾会出现“?”以表示最后一个字节无法识别。
- 所以需要在程序中将这种情况回避掉,只显示整个的汉字字符。
- 第一种方法:通过比较新子串和源字符串相同位置上的字符是否相等来判断新子串中最后一个字节是否可以识别,
- 如果相同则说明最后截取的是一个完整的汉字,如果不同则说明新子串的字节数组最后一个字节是一个汉字的半边,
- 需要舍弃,所以数组指针向左移一位,以保证完整的汉字输出。此方法条理清楚,可阅读性较强。
- 第二种方法:相比较而言,个人觉得第二种方法比较不容易看懂,需要费点儿功夫,
- 首先,在字符串判断的使用使用的是三目运算符,看上去很赞,
- 接下来,再判断新子串是否符合要求时使用了while方法,通过不断的循环比较,
- 数组指针向左移动来获取到最后的字符子串。
- */
- class TestSplitString
- {
- public static void main(String[] args)
- {
- byteSubStr_1("HM程序员训练营",3);
- byteSubStr_2("HM程序员训练营",3);
- }
- public static void byteSubStr_1(String str , int len)
- {
- String s = null; //初始化字符串s,赋值为空
- if(str != null) //传入的字符串不能为空
- {
- byte[] a = null; //初始化字节数组,赋值为空
- try
- {
- a = str.getBytes("GBK"); //将字符串转化为字节数组,GBK码表,此时字节数组的长度为14
- }
- catch (Exception e) //捕捉编码失败异常
- {
- e.printStackTrace();
- }
- //System.out.println("String length:"+a.length);打印字节数组的长度
- if(a.length <= len)
- {
- s = str; //如果要求取出的字节长度大于字节数组应有长度,则将s初始化为str
- }
- else if(len > 0)
- {
- s = new String(a, 0, len); //如果字节长度在字节数组长度范围内,则根据要求取出长度len,创建新的字符串s。
- int length = s.length(); //获取新字符串的长度
- //System.out.println(s.length());
- if(str.charAt(length - 1) != s.charAt(length-1))//如果原字符串中相应位置上的字符与
- //新字符串相应位置上的字符不相等,说明新字符串中相应位置只有半个中文,则应该讲数组指针向左移一位,形成新的子串。
- {
- if(length < 2)
- {
- s = null; //如果新字符串的长度小于2,则将新字符串赋值为空。
- }
- else
- {
- s = s.substring(0, length - 1); //将符合条件的子串复制给s
- }
- }
- }
- }
- System.out.println(s);
- }
- public static void byteSubStr_2(String str, int length)
- {
- if (str == null)
- {
- System.out.println("String is null...");
- }
- else
- {
- int len = length; //获取要截取的字节数
- //System.out.println("len:"+len);
- //System.out.println("strlength:"+str.length());//8
- String s = str.substring(0, str.length() < length ? str.length() : length);
- //判断如果要截取的字节数长度大于原字符串本身的长度,则仍以原字符串为准,否则获取新子串。规则为包含头不包含尾。
- //System.out.println("s1:"+s);
- int byteLens = 0; //初始化字节数组长度
- try
- {
- byteLens = s.getBytes("GBK").length; //按照GBK码表将原字符串或子串转为字节数组,并获取字节数组长度。
- //System.out.println("byteLens:"+byteLens);
- }
- catch (Exception e) //捕获编码异常
- {
- e.printStackTrace();
- }
- while (byteLens > len) //如果字节数组长度大于要截取的字节数,说明有汉语字符的存在
- {
- int subLength = --length;
- //System.out.println("subLength:"+subLength);
- s = str.substring(0, subLength > str.length() ? str.length() : subLength);
- //判断新子串长度和原子串长度,true返回原子串长度,false返回新子串长度
- //System.out.println("s2:"+s);
- try
- {
- byteLens = s.getBytes("GBK").length;
- //System.out.println("byteLens:"+byteLens);
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- }
- System.out.println("String:"+s);
- }
- }
- }
复制代码
作者: 凝霜的枯藤 时间: 2014-4-14 12:38
- package com.itheima;
- import java.io.UnsupportedEncodingException;
- import java.util.Scanner;
- /**
- * 10、 编写函数,从一个字符串中按字节数截取一部分,但不能截取出半个中文(GBK码表)
- * 例如:从“HM程序员”中截取2个字节是“HM”,截取4个则是“HM程”,截取3个字节也要是"HM"而不要出现半个中文
- * @author Say
- *
- */
- public class Test10 {
-
- public static void main(String[] args) {
- System.out.println("请输入截取的字节数:");
- Integer byteNum = new Scanner(System.in).nextInt();
- //调用函数现实截取
- String subString = subStringBybyte("HM程序员你好中国人",byteNum);
- //输出所得结果
- System.out.println(subString);
- }
- /**
- *
- * @param data
- * @param byteNum
- * @return
- */
- private static String subStringBybyte(String data, Integer byteNum) {
- String subString = null;
- try{
- if(data!=null&&!"".equals(data)){
- //如果字符串不为NULL或者是空字符串,将转为GBK编码的字符串
- data = new String(data.getBytes(), "GBK");
- if (byteNum>=1 && byteNum<data.getBytes("GBK").length) {
- StringBuffer buffer = new StringBuffer();
- char ch;
- for (int i=0; i<byteNum; i++)
- {
- ch=data.charAt(i);
- buffer.append(ch);
- // 判断是否为中文字符,如果是中文字符,将截取字节总数减1
- if (Test10.isChineseChar(ch)) {
- --byteNum;
- }
- }
- subString = buffer.toString();
- }
- }
- }catch (Exception e) {
- e.printStackTrace();
- }
- return subString;
- }
- /**
- * 采用GBK编码方式时,一个中文字符占2个字节
- * 判断字符串某个字符是否是中文字符
- * @param c
- * @return
- * @throws UnsupportedEncodingException
- */
- public static boolean isChineseChar(char c)
- throws UnsupportedEncodingException {
- byte[] b = String.valueOf(c).getBytes("GBK");
- if(b.length==2){
- return true;
- }else{
- return false;
- }
- }
- }
复制代码
作者: dongdong5982 时间: 2014-4-15 08:56
试试这种方法,使用String类中的substring方法- public static String getStr(int n,String str)
- {
- return str.substring(0, n);
- }
-
- public static void main(String[] args) {
- System.out.println(getStr(2,"黑马我来喽"));
- }
复制代码
作者: 郭珍 时间: 2014-4-15 11:49
package com.itheima;
/**
* 第10题:编写函数,从一个字符串中按字节数截取一部分,但不能截取出半个中文(GBK码表)
*
* 例如:从“HM程序员”中截取2个字节是“HM”,截取4个则是“HM程”,截取3个字节也要是"HM"而不要出现半个中文
*/
class SplitString {
//私有化成员变量
private String str;
private int byteNum;
//构造函数
public SplitString(){}
public SplitString(String str,int byteNum){
this.str=str;
this.byteNum=byteNum;
}
//定义方法实现功能
public void splitIt(){
byte bt[]=str.getBytes();
System.out.println("Length of this String="+bt.length);
//按照字节数进行判别并分类
if (byteNum >= 1) {
if (bt[byteNum] < 0) {
String substrx =new String(bt ,0,-- byteNum);
System.out.println(substrx);
}else{
String substrx =new String(bt ,0,byteNum);
System.out.println(substrx);
}
}else{
System.out.println("输入错误,请输入大于零的整数:");
}
}
}
//主函数
class Test10 {
public static void main(String[] args) {//主函数是程序的入口
//赋值
String str="HM程序员";
int num=3;
//并按字节截取字符
SplitString sptsr= new SplitString(str,num);
sptsr.splitIt();
}
}
作者: Без_тебя 时间: 2014-6-12 22:19
具体思路是这样的,先把字符串分解成gbk字节数组,然后把截取的那一段字节数组合并成字符串,然后比较最后一个字符是否相等,不想等就是最后一个字符有问题,删了就行~~
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) |
黑马程序员IT技术论坛 X3.2 |