【问题标题】:COBOL Question - UNICODECOBOL 问题 - UNICODE
【发布时间】:2011-05-11 05:33:10
【问题描述】:

我们目前正在寻求将旧的 COBOL 代码从 ANSII 转换为 UNICODE,但是我们遇到了一个问题,即当数据结构包含 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 where ???是十六进制的 X"313233343536"。

我们的问题是我们有多个数据记录,具体取决于记录类型标识符,我们还在许多 LINKAGE 项目上使用重新定义。

有人有从传统 ASCII 转换为 UNICODE 的经验吗?

【问题讨论】:

    标签: cobol


    【解决方案1】:
    02 WS-NUM PIC 9(6) USAGE NATIONAL.
    

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

    【讨论】:

    • 感谢您的回答,我相信这对于 zOS 的 IBM COBOL 是正确的,但我们正在 Windows 平台上使用 MicroFocus。
    【解决方案2】:

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

    感谢大家的帮助。

    【讨论】:

      【解决方案3】:

      如果我理解正确,您希望将 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 字段。

      【讨论】:

      • 实际上,我想使用 REDEFINES,因为它适用于 ASCII,但这是不可能的,因为我必须重新处理代码的许多部分,而且这个解决方案不适用于 S9(n )、S9(n) COMP 或 S9(n)V9(n) 字段。当使用标准 ASCII 时,它可以按字节处理字节并正确表示值。对于 PIC S9(n).... ELEMENTRY 项目,这些项目通常用于 01 GROUP 级别并且可以正常工作。
      • @bottomline:底线是您没有说有 COMP 和签名字段。你写了更多的转换程序。
      【解决方案4】:

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

      (更新了更好的解决方案)

      【讨论】:

      • 这或多或少是正确的,但它仍然需要对现有代码进行大量返工,而且它无法处理我们在数据结构中的 PIC S9(n) 类型变体/可以重新定义。我从 Micro Focus 收到的解决方案与您提到的相同。
      • 是的,它确实有一个长度错误......但这修复了它...... MOVE FUNCTION DISPLAY-OF(WS-RECORD-1( 1:LENGTH OF WS-RECORD(1:6) ),1252) 到 WS-NUM
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-05-13
      • 2010-12-26
      • 2011-11-09
      • 2013-02-12
      • 2010-12-16
      • 2023-03-08
      • 1970-01-01
      相关资源
      最近更新 更多