2015-01-23 12:45:17 middilestep 阅读数 508

汉字编码及LINUX中文处理  

2010-12-28 12:07:42|  分类:linux学习 |  标签:utf  编码  unicode  字节  汉字  |举报|字号 订阅

字符编码类型
 
   英文字符,使用ASCII,用一个byte表示即可.ASCII码一共规定了128个字符的编码,比如空格“SPACE”是32(二进制 00100000),大写的字母A是65(二进制01000001)。这128个符号(包括32个不能打印出来的控制符号),只占用了一个字节的后面7 位,最前面的1位统一规定为0。
   汉字用一个byte来表示明显不够,因此最早的汉字编码,是采用两个byte来表示.同时为了与原来ascii英文字符不混淆.特别规定:
     两个大于127的字符连在一起时,就表示一个汉字,前面的一个字节(他称之为高字节)从0xA1用到 0xF7,后面一个字节(低字节)从0xA1到0xFE,这样我们就可以组合出大约7000多个简体汉字了。在这些编码里,我们还把数学符号、罗马希腊的 字母、日文的假名们都编进去了,连在 ASCII 里本来就有的数字、标点、字母都统统重新编了两个字节长的编码,这就是常说的"全角"字符,而原来在127号以下的那些就叫"半角"字符了。 这个方案称为GB2312编码.一般称为国标码.
    在计算机在中国开始普及年代,如DOS/WIN3.1/win95等阶段.GB2312立下了汗马功劳.在同一时期,以繁体字为主的台湾也搞一套类似的编码,称为BIG5编码.原理是一样的,但是与GB2312码有冲突.
  
    但是GB2312.还有很多缺点,一是字符集太小,只能表示几千个常用汉字.大量汉字没法表示,二是其它汉字表示集BIG5有冲突,经常出现乱码的情况.三是如果出现几种文字需要同时显示,如阿拉伯文,泰文等无法实现.这种情况在互联网时代尤其明显.
 
UNICODE
 
    为了解决全世界文字冲突问题,ISO把所有常用语言的字符,全部统一编码,称为"Universal Multiple-Octet Coded Character Set",简称 UCS,或称UNICODE方案.
  它规定所有字符包括英文字符由2个字节表示.但为了的兼容.原来的ASCII码高位字节全部采用0,低位就是原来ASCII值. 
   
   需要注意的是,Unicode只是一个符号集,它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储。我们一般称为UNICODE表示,是 指用两个byte来,即一个Short来表示的方法.2个字节在32位CPU上正好是一个short型,这样在不同字节序的CPU下,同一个编码有两种排 序,默认是小端字节序.也有按大端字节序,两种方案分别称为Unicode,Unicode-Big.
     这样就造成一个编码有多种存储方式,这样造成推广的不便.
 
  UNICODE 在制订时没有考虑与任何一种现有的编码方案保持兼容,这使得 GBK 与UNICODE 在汉字的内码编排上完全是不一样的,没有一种简单的算术方法可以把文本内容从UNICODE编码和另一种编码进行转换,这种转换必须通过查表来进行.
 
  
  
UTF-8
随着互联网兴起,如何在网络上传输字符UNICODE也是一个问题.于是面向传输的众多 UTF(UCS Transfer Format)标准出现了,顾名思义,UTF8就是每次8个位传输数据,而 UTF16就是每次16个位,
 

UTF-8最大的一个特点,就是它是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。

UTF-8的编码规则很简单,只有二条:

1)对于单字节的符号,字节的第一位设为0,后面7位为这个符号的unicode码。因此对于英语字母,UTF-8编码和ASCII码是相同的。

2)对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的unicode码。

下表总结了编码规则,字母x表示可用编码的位。

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

下面,还是以汉字“严”为例,演示如何实现UTF-8编码。

已知“严”的unicode是4E25(100111000100101),根据上表,可以发现 4E25处在第三行的范围内(0000 0800-0000 FFFF),因此“严”的UTF-8编码需要三个字节,即格式是“1110xxxx 10xxxxxx 10xxxxxx”。然后,从“严”的最后一个二进制位开始,依次从后向前填入格式中的x,多出的位补0。这样就得到了,“严”的UTF-8编码是 “11100100 10111000 10100101”,转换成十六进制就是E4B8A5。

 
GBK
    GBK编码(Chinese Internal Code Specification)是中国大陆制订的、等同于UCS的新的中文编码扩展国家标准。gbk编码能够用来同时表示繁体字和简体字,而gb2312只 能表示简体字,gbk是兼容gb2312编码的。GBK工作小组于1995年10月,同年12月完成GBK规范。该编码标准兼容GB2312,共收录汉字 21003个、符号883个,并提供1894个造字码位,简、繁体字融于一库。Windows95/98简体中文版的字库表层编码就采用的是GBK,通过 GBK与UCS之间一一对应的码表与底层字库联系。
 
 
  一般有时把ASCII与GB2312混排称为ANSI,它与UTF-8,UNICODE,UNICODE BIG称为四种编码.
 
WINDOW的记事本支持四种编码汉字
  
 
 
文本文件类型
   因为并存好几种编码,软件处理文本文件是如何判断类型的?实际如果不加一些附加信息,软件也难判断文本是哪一种格式.一般是文件前面加入BOM(Byte Order Mark)码.其中有下表.
Bytes Encoding Form
00 00 FE FF        UTF-32, big-endian
FF FE 00 00        UTF-32, little-endian
FE FF        UTF-16, big-endian/即一般的UNICODE-BIG
FF FE        UTF-16, little-endian/即UNICODE
EF BB BF        UTF-8
 
这样只要打开文本文件内容,查看0-3 byte是否这一些数字,即判断出是哪一种格式.如果全部都不是,意味着是ANSI编码.
 
关于BOM,更详细参见
 
一些编码格式一般是约定成俗的,如*.lrc,往往使用ASCII与GB码混排,即ANIS格式.C源程序采用ASCII.但中间的汉字在不同系统下有不同规定LINUX采用UTF-8,WINDOWS采用GB码.
 
 
Windows/Unix 文本回车符.
 
   处理文本文件还有一个细节,是WINDOWS的每行回车符两个字符,\r\n,而UNIX回车符一个字符是\n,而它还有一个特殊规定,最后一行是空行, 即\n\n结尾.大部分软件能识别两种格式,但是WINDOWS记事本打开LINUX文本文件时,并不换行而是显示黑框.
   但fgets之类实现是最早在UNIX实现,所有读出来最后的字符都是\n,WINDOWS上也是如此.必须用fopen(name,"rb")然后用fread才能读出\r\n来.
  
标装C宽字节类型
  strlen(),计算结果只针对ASCII有效,对于2个BYTE字节无法处理.因此标准C中,制定了wchar_t,它一般被定义成unsigned short 型.对宽字节的函数要采用新的w打头的接口.
如求宽字符字符串的长度的函数是
#include <wchar.h>
size_t wcslen(const wchar_t *s);
 
Linux 下汉字处理
 
   Linux 下的汉字编码是以UTF-8,这从RHEL的中文版的语言就可以知道,中文环境下,环境变量LANG的值为 zh_CN.UTF8,而WINDOWS自WINDOWS NT开始,内部都采用UNICODE表示.因此两者在编程有着细微差别.
   如果是带汉字的文本可参考相应的BOM来处理.但是在显示,打印时要因应不同的系统采用不同格式.
   如LINUX下控制台下,需要UTF-8格式才能正确处理.象SDL的图形界面下,汉字要转成UNICODE或UTF-8才能正常显示.文本文件还好处理.
   但如果在C代码里出现汉字常量
   如printf("黄新宇\n");,这个有不同的情况.如果这个C代码是在LINUX编辑,则C源程序中是UTF-8直接可以显示,如果这个C代码是在WINDOWS编辑拷贝过来.则很有可能是GB码,这样程序编译后在LINUX控制台上乱码.
  
 
  putty 下汉字显示,需要将字体换成UTF-8才能正常显示




http://baike.baidu.com/link?url=TUpGgnZf4hDoNO9gdoNv4PKd-yK1O3-RH9UEXyKzbWajWVkcW0JHLpovv0OR7HepAs2__Ib8LOzUOMOX479Su_
 
另外LINUX中文文件名也是UTF-8编码的,可以在fopen中直接采用中文编码.如果WINDWOS的中文则有可能是UNICODE编码,但在samba拷贝后会自动转换
2017-05-26 17:48:30 sinat_21302587 阅读数 6604

大家可能遇到这样的情况,比如你在终端敲下 cd 命令,删除时需要 backspace 或者 delete 两次。

而如果敲下了 ”吃饭“ 删除时有的机器上只backspace 或delete 两次是不行。必须多次删除。通常是字符的2倍。

这是为什么呢???

echo $LANG

如果返回LANG=C

则表明默认的编码方式为ascii ,普通的英文一个字节表示一个字母,而汉字则需要两个字节表示。因此删除是,理论上就要double。

vim /etc/profile

在最后加上

export LC_ALL="en_US.UTF-8"  
export LANG="en_US.UTF-8"

当然我也看到有些博客上写的是 zh_CN.UTF_8 大家可以自己试试。

修改完成后运行
source /etc/profile

这样就解决了汉字删除时的小问题

2018-05-10 12:55:21 Mr_Xuf 阅读数 866

在Linux终端中输入ls -l,打印出的情况如下图1所示

图1

以图1中第四行(汉字公共的所在行)为例进行说明。

d rwx r-x r-x. 2 root root 4096 4月   26 20:57 公共的 

在以上示意图中

第一列(灰底):表示文件的类型与权限

在第一列中一共有10个字符,以1,3,3,3分组,其中r为可读;w为可写;x为可执行;rwx位置不变,没有以-替。

第1个字符:表示文件类型,d表示目录;-表示文件;l表示链接;b表示接口设备;c表示串行接口设备(鼠标等);

第2~4三个字符:表示文件所有者的权限(User)

第5~7三个字符:表示同一用户组下其他用户权限(Group)

第8~10三个字符:表示其他用户权限(不在同一用户组下)(Other)

第二列(黄底):表示连接,既有多少文件名连接到此节点

第三列(棕地):表示文件所有者

第四列(橙底):表示文件的所属用户组

第五列(红底):表示文件大小,默认单位为B

第六列(粉底):表示修改或创建时间,假如时间太久就只会显示年份哦

第七列(绿底):表示文件名称

-------------------------------------------- 以下为修改文件属性与权限常用命令------------------------------------------------

chmod:改变文件的权限

 

方法一:用数字更改文件权限;rwx的排列顺序不变,有的话用1表示,没有(-代替)用0表示,即421码。上面示意图为755

 

实例改变/home/test01/hello.c的权限,如图2所示,若加上-r选项则是对目录下的所有文件递归更改。

图2

方法二:用符号更改文件权限;格式:chmod [who] [+ 或 – 或 =] [mode]  文件名

 

 

[who]:u 表示文件的所有者。g 表示与文件所有者同组的用户。o 表示“其他用户”。a表示“所有用户”。它是系统默认值。

+ 添加某个权限;- 取消某个权限;= 赋予给定权限

[mode]:r(read)读权限;w(write)写权限;x(execute)执行权限

翻译过来也就是说 谁加上或减去某个权限,注意不同用户间用“,”隔开喔

举例:(1)chmod u-x,g+w,o-r hello.c  即取消文件所有者x权限,增加同用户组w权限,取消其他用户r权限。如图3所示。

图3

chown:改变文件所用者(其实他也可以修改用户组的名称)

在使用复制命令(cp)时,即使将文件给了其他用户,由于复制将文件的属性和权限一起复制,所以其他用户还是无法使用该文件,对文件所有者的修改如图4所示。

图4

chgrp: 改变文件所属用户组

补充:添加用户组指令,groupadd [-选项] [用户组名];删除用户组指令groupdel [-选项] [用户组名]注意:要被改变的组名必须要在/etc/group文件内才可以(命令vi /etc/group可以查看),否则会报错。

对文件所属用户组的修改如图5所示

图5

欢迎大家加C/C++ Linux 技术栈开发群:786177639,一起交流学习

2020-03-10 13:27:10 baidu_16370559 阅读数 6
Unicode通常用两个字节表示一个字符
采用Unicode编码,所以一个QChar占用两个字节
UTF-16:使用二或四个字节为每个字符编码,其中大部分汉字采用两个字节编码,少量不常用汉字采用四个字节编码。是任何字符对应的数字都用两个字节来保存,但如果都是英文字母(一个字节能表示一个字符)这样做有点浪费。由于UTF-16不需要用其它字符来做标志,所以两字节也就是2的16次能表示65536个字符
UTF-8:是任何字符对应的数字保存时所占的空间是可变的,使用一至四个字节为每个字符编码,其中大部分汉字采用三个字节编码,少量不常用汉字采用四个字节编码.而UTF-8由于里面有额外的标志信息,所有一个字节只能表示2的7次方128个字符,两个字节只能表示2的11次方2048个字符,而三个字节能表示2的16次方,65536个字符
UTF-8  0xxxxxxx:如果是这样的格式,也就是以0开头就表示把一个字节做为一个单元,就跟ASCII完全一样;
       110xxxxx  10xxxxxx:如果是这样的格式,则把两个字节当一个单元;
       1110xxxx 10xxxxxx 10xxxxxx:如果是这样的格式,则把三个字节当一个单元                                                                      1110xxx 10xxxxxx 10xxxxxx 10xxxxxx:四字节编码形式
wchar_t类型在Windows和Linux平台下的大小时不一样的,Windows下采用的是2字节编码一个字符,基于utf-16。 Linux下采用的是4个字节编码一个字符,基于utf-32。还有一点,不能贸然的添加gcc 编译项 -fshort-wchar,强制将Linux平台下的wchar_t指定成两个字节,因为这样做,只会改变你在代码中自己实现的部分,而内部库或者是第三方库中用到的接口和函数都是没有变的,仍然采用的是4字节编码。如,std::wstring, QT中的QString等。
在Linux下写入wchar_t类型的数据的时候,需要先把Linux下的wchar_t的编码格式转成Windows下的wchar_t编码格式,读的时候同理,需要先把读出来的Windows下的wchar_t数据,转成Linux下的wchar_t数据,这样就能实现两个平台下的数据读写,而且夜兼容了以前的数据文件。在Linux下的转换函数也采用的是iconv(),在头文件<iconv.h>中。iconv()的用法如下:
iconv函数族的头文件是iconv.h。
#include <iconv.h>
iconv函数族有三个函数,原型如下:
(1) iconv_t iconv_open(const char *tocode, const char *fromcode);
此函数说明将要进行哪两种编码的转换,tocode是目标编码,fromcode是原编码,该函数返回一个转换句柄,供以下两个函数使用。
(2) size_t iconv(iconv_t cd,char **inbuf,size_t *inbytesleft,char **outbuf,size_t *outbytesleft);
此函数从inbuf中读取字符,转换后输出到outbuf中,inbytesleft用以记录还未转换的字符数,outbytesleft用以记录输出缓冲的剩余空间。 (3) int iconv_close(iconv_t cd);
此函数用于关闭转换句柄,释放资源。     
2010-09-17 17:55:00 chihuanqi 阅读数 2615

环境: jfreechart.jar在服务器端生成含有宋体汉字的图片, 需要服务器端正确配置宋体, 中间件是webLogic8.1.6, jdk是1.4.2

 

linux系统

jdk版本是:sun jdk142_11

一、将windows的simsun.ttc拷贝至/bea/jdk14x_xx/jre/lib/fonts/,并改名为simsun.ttf

二、修改/bea/jdk14x_xx/jre/lib/fonts/fonts.dir 文件,将第一行的 72(表示字体个数) 改为73,最后一行加上:

simsun.ttf -Arphic Technology Co.-AR PL SungtiL GB-medium-r-normal--0-0-0-0-c-0-gb2312.1980-0

三、修改 /bea/jdk14x_xx/jre/lib/font.properties.zh(如果不存在,就把font.properties.zh.Turbo另存为font.properties.zh),将文件中所有的:

-tlc-song-medium-r-normal--*-%d-*-*-c-*-gbk-0 替换为:

-Arphic Technology Co.-AR PL SungtiL GB-medium-r-normal--0-0-0-0-c-0-gb2312.1980-0

四、增加weblogic的启动参数

JAVA_OPTIONS="-Ddefault.client.encoding=GBK -Dfile.encoding=GBK -Duser.language=Zh -Djava.awt.headless=true -Duser.region=CN -Dcharset=IS08859-1"

 

 

 

 

AIX系统

jdk版本:IBM(R) 32-bit SDK for AIX(TM), Java(TM) 2  Technology Edition, Version 1.4.2

一、将windows的simsun.ttc拷贝至${JAVA_HOME}/jre/lib/fonts/,并改名为simsun.ttf

二、修改${JAVA_HOME}/jdk14x_xx/jre/lib/fonts/fonts.dir 文件,将第一行的 168(表示字体个数) 改为169,最后一行加上:

simsun.ttf -zhongyi-song-medium-r-normal--0-0-0-0-m-0-gbk-0

修改${JAVA_HOME}/jdk14x_xx/jre/lib/fonts/fonts.scale 文件,将第一行的 168(表示字体个数) 改为169,最后一行加上:

simsun.ttf -zhongyi-song-medium-r-normal--0-0-0-0-m-0-gbk-0

三、修改 ${JAVA_HOME}/jre/lib/font.properties.zh,将文件中所有的:

-Monotype-TimesNewRomanWT-medium-r-normal--*-%d-75-75-*-*-gb2312.1980-0 替换为:

-zhongyi-SimSun-medium-r-normal--0-0-0-0-m-0-gbk-0

在# font filenames的文件块末尾增加(可能是130行)

filename.simsun_medium_r=simsun.ttf

四、增加weblogic的启动参数

JAVA_OPTIONS="-Ddefault.client.encoding=GBK -Dfile.encoding=GBK -Duser.language=Zh -Djava.awt.headless=true -Duser.region=CN -Dcharset=IS08859-1"

 

重启服务,检查生成的图片是否正常显示.

 

如果没有正确配置中文字体, 中文会不显示或是显示方框.

没有更多推荐了,返回首页