我们目前正在寻求将我们的旧版COBOL代码从ANSII转换为UNICODE但是我们遇到的问题是,只需将PIC X字段更改为PIC N并设置NSYMBOL(NATIONAL),当数据结构包含REDEFINES或使用PIC 9字段的基本DATA项的RENAME语句。
01 WS-RECORD PIC N(26).
01 WS-RECORD-1 REDEFINES WS-RECORD.
02 WS-NUM PIC 9(6).
02 WS-DATA PIC N(20).
MOVE N"123456ABCDEFGHIJKLM" TO WS-RECORD.
在上面,被移动的字符串将是UTF-16格式,因此字段WS-NUM将被破坏,因为它将包含X“310032003300”,这是一个无效的数字,WS-DATA将包含X“3400350036004100。 .etc
问题是,当使用NATIONAL(UTF-16)数据类型时,如何处理数字以便在重新定义数据后获得正确的数据。
我可以尝试执行以下操作,但会在其他WS-RECORD中获取无效数据。
MOVE 123456 TO WS-NUM.
MOVE N"ABCDEFGHIJKLM" TO WS_DATA.
以上将是正确的,但如果我检查WS-RECORD我会看到??? ABCDEFGHIJKLM在哪里???是hexi-decimal的X“313233343536”。
我们的问题是我们根据记录类型标识符有多个数据记录,我们还在许多LINKAGE项目上使用重新定义。
有没有人有从旧版ASCII转到UNICODE的经验?
答案 0 :(得分:3)
02 WS-NUM PIC 9(6) USAGE NATIONAL.
应该有效(至少在IBM编译器上)。
答案 1 :(得分:3)
MicroFocus建议的解决方案如下: -
WS-NCHAR-1和WS-NCHAR-FIELD的大小是不同的大小,因为“pic 9(6)”的大小是“pic n(6)”的一半大小。
所以快速但不整洁的解决方案是放置一个填充物,然后使用“FUNCTION DISPLAY-OF”重新校正该字段,虽然这有效,但客户真的需要了解“pic n”的大小不同于“pic 9”,因此在使用重新定义和转换期间需要小心。
一个经过调整的例子,可以告诉你我在代码中的意思......
01 ONE-PICN PIC N.
01 ONE-PIC9 PIC 9.
01 WS-NCHAR-FIELD PIC N(20).
01 WS-NCHAR-1 REDEFINES WS-NCHAR-FIELD.
02 WS-NUM PIC 9(6).
02 FILLER PIC X(6).
02 WS-REST PIC N(14).
DISPLAY "PIC N SIZE : " length of ONE-PICN
DISPLAY "PIC 9 SIZE : " length of ONE-PIC9
DISPLAY "WS-NCHAR-FIELD : " length of WS-NCHAR-FIELD
DISPLAY "WS-NCHAR-1 : " length of WS-NCHAR-1
DISPLAY "WS-REST : " length of WS-REST
DISPLAY "WS-NUM : " length of WS-NUM
MOVE N"123456ABCDEFGHIJKLM" TO WS-NCHAR-FIELD.
MOVE FUNCTION DISPLAY-OF(WS-NCHAR-FIELD(1:6),1252) TO WS-NUM
DISPLAY "WS-NUM : " WS-NUM DISPLAY "WS-REST : " WS-REST
以上不适用于S9(n)COMP或S9(n)V9(n)ELEMENTRY ITEMS,使用VISUAL COBOL我发现我可以直接将数值移到PIC N(n)ELEMENTS中,然后使用FUNCTION NUMVAL()获取实际数字,我还没有尝试使用Signed / COMP和十进制字段。
感谢大家的帮助。
答案 2 :(得分:1)
如果我理解正确,你想将X'3000'转换为X'30',X'3100'转换为X'31,依此类推,通过X'3900'转换为X'39'。
我查看了MicroFocus文档,找不到可以执行此操作的内部函数。
您可以定义自己的程序来执行此操作。
该程序的工作存储空间如下所示:
01 WS-NUMERIC-CONVERSION.
05 WS-LOOP-COUNT PIC S9(04) COMP.
05 WS-NATIONAL-POSITION PIC S9(04) COMP.
05 WS-NUMBER-OF-CHARACTERS PIC S9(04) COMP.
05 WS-NATIONAL-INPUT.
10 WS-NATIONAL-INPUT-BYTE PIC X
OCCURS 40 TIMES.
05 WS-ASCII-OUTPUT.
10 WS-ASCII-OUTPUT-BYTE PIC X
OCCURS 20 TIMES.
程序如下:
NATIONAL-TO-ASCII.
PERFORM VARYING WS-LOOP-COUNT FROM 1 BY 1
UNTIL WS-LOOP-COUNT > WS-NUMBER-OF-CHARACTERS
COMPUTE WS-NATIONAL-POSITION = WS-LOOP-COUNT + WS-LOOP-COUNT - 1
MOVE WS-NATIONAL-INPUT-BYTE(WS-NATIONAL-POSITION)
TO WS-ASCII-OUTPUT-BYTE(WS-LOOP-COUNT)
END-PERFORM.
调用程序如下所示:
05 WS-NATIONAL-NUMBER-X.
10 WS-NATIONAL-NUMBER PIC N(06).
05 WS-ASCII-NUMBER-X.
10 WS-ASCII-NUMBER PIC 9(06).
MOVE something TO WS-NATIONAL-NUMBER
MOVE WS-NATIONAL-NUMBER-X TO WS-NATIONAL-INPUT
MOVE +6 TO WS-NUMBER-OF-CHARACTERS
PERFORM NATIONAL-TO-ASCII
MOVE WS-ASCII-OUTPUT TO WS-ASCII-NUMBER-X
MOVE WS-ASCII-NUMBER TO something else
我定义的过程工作存储处理最多20个字符的数字。如果这还不够,请将WS-NATIONAL-INPUT
和WS-ASCII-OUTPUT
字段设置得更大。
答案 3 :(得分:1)
您可以使用DISPLAY-OF FUNCTION和参考修改并添加填充物以确保尺寸平衡,添加78以减少幻数使用!
无论如何,正如我所说的那样有点脏但是有效..
例如:
MOVE FUNCTION DISPLAY-OF(WS-RECORD-1(
1:LENGTH OF WS-RECORD(1:6)),1252)
更新的程序为:
78 NUM-SIZE VALUE 6.
01 WS-RECORD PIC N(26).
01 WS-RECORD-1 REDEFINES WS-RECORD.
02 WS-NUM PIC 9(NUM-SIZE).
02 FILLER PIC X(NUM-SIZE).
02 WS-DATA PIC N(20).
MOVE N"123456ABCDEFGHIJKLM" TO WS-RECORD.
DISPLAY "WS-NUM : " WS-NUM
DISPLAY "WS-DATA : " WS-DATA
MOVE FUNCTION DISPLAY-OF(WS-RECORD-1(
1:LENGTH OF WS-RECORD(1:NUM-SIZE)),1252)
TO WS-NUM
DISPLAY "WS-NUM : " WS-NUM
DISPLAY "WS-DATA : " WS-DATA
(用更好的解决方案更新)