在400上汉字如果截取不当,会出现乱码,造成整条记录显示得不正常。
C* INCHAR为原始字段;OUTCHAR为输出字段
C* I1LEN 为需要取出的长度。所以I1LEN不能大于INCHAR的总长度
C*
C MOVEL *BLANKS INCHAR 64
C MOVEL *BLANKS OUTCHAR 64
C Z-ADD *ZERO I1LEN 3 0
C*
C EVAL INCHAR = '很长一个字符串'
C*假设需要取出30位长
C EVAL I1LEN = 30
C*********************************************************************
C* CHARBIT为取1位字符临时变量,判断是否为汉字指示器
C* NN用来判断循环时取第几位
C* KK用来判断当发现汉字指示器时,循环到了第几次
C MOVEL *BLANKS CHARBIT 1
C Z-ADD *ZERO NN 3 0
C Z-ADD *ZERO KK 3 0
C*
C EVAL NN = I1LEN + 1
C*
C DOW NN > 1
C EVAL NN = NN-1
C EVAL CHARBIT=%SUBST(INCHAR:NN:1)
C EVAL KK=I1LEN-NN
C**************************
C*最后两位即发现汉字指示器
C**************************
C SELECT
C WHEN CHARBIT=X'0E' AND KK=0
C EVAL OUTCHAR=%SUBST(INCHAR:1:(I1LEN-1))
C LEAVE
C*
C WHEN CHARBIT=X'0E' AND KK<=2 AND KK>0
C EVAL OUTCHAR=%SUBST(INCHAR:1:NN)+X'0F'
C LEAVE
C**************************
C*指示器后有一个字的空间
C**************************
C WHEN CHARBIT=X'0E' AND KK>2
C KK DIV 2 WWLOOP 2 0
C MVR WWLEFT 1 0
C IF WWLEFT=0
C EVAL OUTCHAR=%SUBST(INCHAR:1:(I1LEN-2))+X'0F'
C ELSE
C EVAL OUTCHAR=%SUBST(INCHAR:1:(I1LEN-1))+X'0F'
C ENDIF
C LEAVE
C**************************
C*发现结束指示器直接赋值
C**************************
C*只要发现0E指示器,即表示有汉字;
C*所以如果一直未发现0E,而发现的第一个指示器为0F
C*那之前倒序查找的肯定都不是汉字,所以可以直接赋值
C WHEN CHARBIT=X'0F'
C EVAL OUTCHAR=%SUBST(INCHAR:1:I1LEN)
C LEAVE
C ENDSL
C**************************
C*未发现指示器
C**************************
C IF NN=1
C EVAL OUTCHAR=%SUBST(INCHAR:1:I1LEN)
C ENDIF
C*
C ENDDO
C*
C* DSPLY OUTCHAR
C EVAL *INLR = '1'
just a kid 回复于:2005-12-15 10:35:09
顶顶,好贴呀
USING_AS400 回复于:2005-12-15 11:34:19
顶一下!
chinagirlwang 回复于:2006-05-22 17:11:52
明明 INCHAR = '很长一个字符串'
为什么老是 CHARBIT=X'0F' 呢?
leason 回复于:2006-05-22 17:58:39
如果是单为了取值不出现乱码的话,楼主的程序好象有点复杂:em15:
[ 本帖最后由 leason 于 2006-5-22 18:35 编辑 ]
leason 回复于:2006-05-22 18:22:37
""在400上汉字如果截取不当,会出现乱码,造成整条记录显示得不正""
如果单凭是这个原因,按楼主说的这个程序实在有点麻烦!个人提供自写的程序给楼主您参考一下!
首先不管定义一个字符的变量数组,长度是多少,由个人自行定义,这里举例我们要进行取值的变量(ABC)长度为100 O的类型, 而这100个长度中存在一位长度的字符或者数字,以及2位长度中文.如我们要取这100位上前50位给(DDD 50 O)
程序如下
0014.00 E ARA1 50 1
*
C MOVE ' ' OF 1
C MOVEL' ' OE 1
**********
* SRT100
**********
C SRT100 BEGSR
C Z-ADD 0 OEOF 10
C MOVELABC DDD 50
C MOVEADDD ARA1
C 1 DO 50 I 20
C ARA1,I IFEQ OE
C ADD 1 OEOF
C ENDIF
C ARA1,I IFEQ OF
C SUB 1 OEOF
C ENDIF
C ENDDO
C OEOF IFEQ 1
C MOVE OF DDD
C ENDIF
C ENDSR
最后取值后的DDD就是我们想要的50位长度.程序会自动判别是否有中文而给予中文字段头尾的箭!
头!因为个人比较麻烦写字,所以写得简略一下!
以上解析不知道大家看明白没有.没明白的话,我再提供完整的RPG程序!
[ 本帖最后由 leason 于 2006-5-22 18:32 编辑 ]
leason 回复于:2006-05-22 18:46:05
不好意思.弄错了,因为看见在论坛的最前面一个帖子,我还以为是刚发的!不好意思!
hsiang_wang 回复于:2006-05-26 16:52:07
不错,前段时间刚解决此问题!
胖有型 回复于:2006-05-30 09:49:21
引用:原帖由 leason 于 2006-5-22 18:22 发表
OEOF IFEQ 1
C MOVE OF DDD
C ENDIF
C ENDSR
...
要只是判断是否需要加“0F”,当然会简单很多;
最早发现这个问题的时候,我是直接强行在截取出来的字符串后面加“0F”,不过仍然会有乱码;
原因也很简单,并不是因为“0E”与“0F”不匹配,而是因为截取的长度不可能刚好在一个汉字结束的地方。
比如说一个字符串:
“0E楼主的程序写得很复杂0F”,
如果截取5位,那么很好,可以取出“0E楼主”,赋值到变量DDD中,然后我们再自动加“0F”;
但是如果只取4位,“主”字就只取出半边,这时就会出现乱码,用debug可以很清楚地观察到;
当取到半边字时,我认为最好的办法就是不要了,也就是说这时只取3位,只取出一个“楼”字来
|