手机站
网通分站
电信主站
密 码:
用户名:
当前位置 : 主页>程序设计>Java技术>列表

有关汉字编码的一道编程问题

来源:互联网 作者:west263.com 时间:2008-02-23
西部数码-全国虚拟主机10强!40余项虚拟主机管理功能,全国领先!双线多线虚拟主机南北访问畅通无阻!免费赠送企业邮局,.CN域名,自助建站480元起,免费试用7天,满意再付款! P4主机租用799元/月.月付免压金!
//有关汉字编码的一道编程问题
/*不久前网上看到这个题目,我把程序拿来改了一改,并且对原因结果做了一个简要的分析,主要的收获是对GB2312编码及编码相关问题有了一些了解。错误的地方还请大家指正。*/
/*编程:编写一个截取字符串的函数,输入为一个字符串和字节数,
输出为按字节截取的字符串。 但是要保证汉字不被截半个,
如“我ABC”4,应该截为“我AB”,输入“我ABC汉DEF”,6,应该输出为“我ABC”而不是“我ABC 汉的半个”。
*/
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)
{
PBinInt("bt[byteNum]",bt[byteNum]);
System.out.println("bt[" byteNum "] = " bt[byteNum]);//1
System.out.println("bt[" byteNum "] = " (int)bt[byteNum]);//2
System.out.println("bt[" byteNum "] = " (bt[byteNum]&0x000000FF));//3
System.out.println("bt[" byteNum "] = " (bt[byteNum 1]&0XFF));//4
String substrx=new String(bt,0,--byteNum);
System.out.println(substrx);
}
else
{
String substrex=new String(bt,0,byteNum);
System.out.println(substrex);
}

}
else
{
if(byteNum==1)
{
if(bt[byteNum]<0)
{
String substr1=new String(bt,0, byteNum);
System.out.println(substr1);
}
else
{
String subStr2=new String(bt,0,byteNum);
System.out.println(subStr2);
}
}
else
{
System.out.println("输入错误!!!请输入大于零的整数:");
}
}
}
static void pBinInt(String s, int i) {
System.out.println(
s ", int: " i ", binary: ");
System.out.print(" ");
for(int j = 31; j >=0; j--)
if(((1 << j) & i) != 0)
System.out.print("1");
else
System.out.print("0");
System.out.println();
}
}
class TestSplitString
{
public static void main(String args[])
{
String str="我ABCe啊DEFe";
int num=6;
SplitString sptstr = new SplitString(str,num);
sptstr.splitIt();
}
}
/*大致思路是:每个汉字对应两个字节,而每个字节的首位都是1,这样对应的就是一个负数.
当然,这样做其实也不是很严密,具体原因就这里不作详细讨论
*/

/*
结果分析:
'啊'对应的是区号是16位,位号是1,这样计算:

3处的输出为176,在Java中对应的二进制0X000000B0
最后一个字节有用,即10110000对应的区号是176-128-32 =16,
减去128是因为每个字节的第一位总是1,后面7位(即2的七次方)才有用
减去32是因为GB2312规定
同理,4处的输出为161,对应的是位号,161-128-32=1

1,2处的都为为-80(字节转化为整数)
因为10110000变为整数是变成0xFFFFFFB0,是一个负数的补码,对应的原码是0x80000050,这个负数即是-80
值得一提的是为了求代表'啊'的整数,(16 128 32)*256 (1 128 32),在excel中用char函数:
如char((16 128 32)*256 (1 128 32))即可得到'啊'

*/
/*

参考文献:
汉字的编码和表示


1)汉字交换码(国标码) 汉字交换码(国标码)主要用于汉字信息交换。
国标码:以国家标准局1980年颁布的《信息交换用汉字编码字符集"基本集》(代号为GB2312 80)规定的汉字交换码作为国家标准汉字编码。 GB2312 80中共有7445个字符符号: 汉字符号6763个 一级汉字3755个(按汉语拼音字母顺序排列) 二级汉字3008个(按部首笔划顺序排列) 非汉字符号682个 GB2312 80规定,所有的国标码汉字及符号组成一个94 94的方阵。在此方阵中,每一行称为一个"区",每一列称为一个"位"。这个方阵实际上组成一个有94个区(编号由01到94),每个区有94个位(编号由01到94)的汉字字符集。 一个汉字所在的区号和位号的组合就构成了该汉字的"区位码"。其中,高两位为区号,低两位为位号。这样区位码可以唯一地确定某一汉字或字符;反之,任何一个汉字或符号都对应一个唯一的区位码,没有重码。
区位码分布情况如下:
区 号 内 容 1区 键盘上没有的各种符号 2区 各种序号 3区 键盘上的各种符号(按中文方式给出) 4 -5区 日文字母 6区 希腊字母 7区 俄文字母 8区 标识拼音声调的母音及拼音字母名称 9区 制表符号 10- 15区 未用 16-55区 一级汉字(按拼音字母顺序排列) 56- 87区 二级汉字(按部首笔划顺序排列) 88- 94区 自定义汉字

文章整理:西部数码--专业提供域名注册虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!