COBOL 问题 - UNICODE

发布于 2024-11-06 04:58:05 字数 810 浏览 4 评论 0原文

我们目前正在寻求将旧版 COBOL 代码从 ANSII 转换为 UNICODE,但是我们遇到了一个问题,即当数据结构包含 REDEFINES 或 RENAME 语句时,仅将 PIC X 字段更改为 PIC N 并设置 NSYMBOL(NATIONAL) 就会导致问题使用 PIC 9 字段的基本数据项。

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 其中 ??? 是 X"313233343536" 我们的问题是,

具体取决于记录类型标识符,我们还在许多链接项目上使用了重新定义。

我们有多个数据记录, ASCII 到 UNICODE?

We are currently looking to convert our legacy COBOL code from ANSII to UNICODE however we have come across a problem where just changing the PIC X fields to PIC N and setting NSYMBOL(NATIONAL) will cause problems when data structures contain a REDEFINES or RENAME statement with elementary DATA items using PIC 9 fields.

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.

In the above the string being moved will be in UTF-16 format, therefore the field WS-NUM will be corrupt as it will contain X"310032003300" which is an invalid numeric, WS-DATA will contain X"3400350036004100..etc

The question is, when using NATIONAL (UTF-16) data types how can numerics be handled so as to get the correct data after it has been redefined.

I can sort of get this to work doing the following but will get invalid data in other WS-RECORD.

MOVE 123456 TO WS-NUM.
MOVE N"ABCDEFGHIJKLM" TO WS_DATA.

The above will be correct, however if I examine WS-RECORD I will see ???ABCDEFGHIJKLM where ??? is X"313233343536" in hexi-decimal.

Our problem is that we have multiple data records depending on the record type identifier, we also use redefines on many of our LINKAGE ITEMS.

Has anyone had experience moving from legacy ASCII to UNICODE?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

南薇 2024-11-13 04:58:05
02 WS-NUM PIC 9(6) USAGE NATIONAL.

应该可以工作(至少在 IBM 编译器上)。

02 WS-NUM PIC 9(6) USAGE NATIONAL.

Should work (at least on IBM compilers).

猛虎独行 2024-11-13 04:58:05

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) 元素项目,使用 VISUAL COBOL 我发现我可以将数值直接移动到PIC N(n) 元素,然后使用 FUNCTION NUMVAL() 获取实际数字,我还没有尝试使用 Signed/COMP 和小数字段。

感谢大家的帮助。

A solution suggested by MicroFocus is below:-

The size of WS-NCHAR-1 and WS-NCHAR-FIELD are different sizes because the size of “pic 9(6)” is half the size of “pic n(6)”.

So the quick but untidy solution is to place a filler and then re-correct the field by using “FUNCTION DISPLAY-OF”, although this works the customer really needs to understand that the size of “pic n” is different to “pic 9”, hence care is needed when you use redefines and during conversion.

A tweaked example that should show you what I mean in code…

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

The above does not work for S9(n) COMP or S9(n)V9(n) ELEMENTRY ITEMS, with VISUAL COBOL I found that I could just MOVE numeric values directly into PIC N(n) ELEMENTS and then use FUNCTION NUMVAL() to obtain the actual numeric, I am yet to try with Signed/COMP and decimal fields.

Thanks all for your help.

清浅ˋ旧时光 2024-11-13 04:58:05

如果我理解正确的话,您想要将 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-INPUTWS-ASCII-OUTPUT 字段。

If I understand you correctly, you want to convert X'3000' to X'30', X'3100' to X'31, and so on, through X'3900' to X'39'.

I looked through the MicroFocus documentation, and couldn't find an intrinsic function that would do this.

You could define your own procedure to do this.

The working storage for the procedure would look like this:

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.

The procedure would look like this:

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.

Calling the procedure would look like this:

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

The procedure working storage that I defined handles a number up to 20 characters in length. If that's not enough, make the WS-NATIONAL-INPUT and WS-ASCII-OUTPUT fields bigger.

生死何惧 2024-11-13 04:58:05

您可以使用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

用更好的解决方案更新)

You can use the DISPLAY-OF FUNCTION and reference modification and add a filler to ensure the size is balanced, add a 78 to reduce magic number use!

Anyway, as I said its a bit dirty but works..

eg:

  MOVE FUNCTION DISPLAY-OF(WS-RECORD-1(
                 1:LENGTH OF WS-RECORD(1:6)),1252)

With the updated program being:

     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

(updated with a better solution)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文