【问题标题】:Get position of character in collating sequence获取字符在排序序列中的位置
【发布时间】:2017-03-03 21:09:40
【问题描述】:

我正在寻找一种将ASCII文本转换为十六进制数据的方法,我的意思是您可以获得的十六进制方式

MOVE X'nn'  TO MYVAR.

然后我需要像使用数字一样使用它(我猜是 COMP-3)。

我试图将 PIC(X) 移动到 PIC S9(2)V COMP-3,但没有像我想象的那样工作......

进一步解释,因为我的问题被标记为不清楚:

首先,对不起,我在深夜提出这个问题,现在我再次阅读,是的,不清楚。

现在,真正的问题是我想使用 char(比如说“A”),因为它是十六进制数字表示,可以将其用作内部表的索引。

例如,在 C 中可能很容易:

int mynum;
char mytext;

mynum = atoi(mytext);

然后使用mychar 访问一个数组。所以,在 COBOL 中我有:

01 MY-TABLE.
    05 MY-TABLE-ITEM  PIC X OCCURS 1000.

01 MY-TEXT  PIC X 100.
01 MY-TEXT-X PIC X OCCURS 100.

然后,我想迭代 MY-TEXT-X 并将其转换为十六进制代码以将其存储到数字变量 (PIC 9(n)) 中以使用它来访问 MY-TABLE-ITEM,类似于:

PERFORM VARYING I FROM 1 BY 1 UNTIL I > 100
    PERFORM TRANSFORM-DATA

    DISPLAY MY-TABLE-ITEM(MY-NUMBER)
END-PERFORM

正如我所说,我认为我可以将 PIC X 移动到 PIC S9(2)V COMP-3 以便数字变量可以获得值,但它没有按我预期的那样工作......

编辑:

所以我刚刚发现我的编译器不支持内在函数,所以这对我没有帮助......

编辑 - 添加源代码

所以,这是我正在使用的源代码,也显示来自编译器和执行。

来源:

   IDENTIFICATION DIVISION.
   PROGRAM-ID.  likeatoi.
   DATA DIVISION.
   WORKING-STORAGE SECTION.
    01  the-char                            PIC X 
                                          VALUE "K".
    01  the-result                          PIC 999.
    01  the-other-result             PACKED-DECIMAL PIC 9(8) 
                                          VALUE ZERO.
    01  FILLER 
    REDEFINES the-other-result. 
       05  FILLER                          PIC X.
       05  char-to-convert                 PIC X.
    01 num pic 9(8).
   PROCEDURE DIVISION.
   MAINLINE.
  *    with instrinsic function
  *    MOVE FUNCTION ORD ( the-char ) 
  *                              TO the-result.
       DISPLAY 
           ">"
           the-char
           "<"
           ">"
           the-result
           "<".

  *    Old School
       MOVE  the-char               TO char-to-convert.
       DISPLAY 
           ">"
           the-char
           "<"
           ">"
           the-other-result
           "<".

       MOVE the-other-result       TO num.
       DISPLAY num.

       STOP RUN.

现在,这里是我尝试的所有细节:

  1. 首先,尝试用 INTRINSIC FUNCTION ORD 编译它:

    ***** 1) 0384: E User-defined word expected instead of reserved word. (scan su

  2. 通过此编译,运行程序(忽略错误):

COBOL procedure error 211 at line 17 in ./ESCRITORIO/HEX/LIKEATOI.COB (/home/dohitb/Escritorio/HEX/likeatoi.COB) compiled 17/03/05 20:37:29.

  1. 注释FUNCTION部分,然后重新编译:

Errors: 0, Warnings: 1, Lines: 37 for program LIKEATOI.

(显示 COMP 变量的警告,没关系)

  1. 再次执行(没有“num”,仍然有comp变量):

    &gt;A&lt;&gt; &lt;

    &gt;A&lt;&gt;A&lt;

  2. 添加“num”变量,将 char 更改为“K”并将 COMP 更改为 PACKED-DECIMAL(十六进制:4B)

    &gt;K&lt;&gt; &lt;

    &gt;K&lt;&gt;K&lt;

    04900000

所以,正如我所说,这两个选项都不起作用。现在最准确的方法是使用 PACKED-DECIMAL 并重新定义为 PIC 9,但 HEX 位置高于“A”时它给出“9”,所以它仍然无效。

我认为这可能是本地 COLLATION 的问题。

最终编辑

现在我做了一个原始源代码的变体:

   IDENTIFICATION DIVISION.
   PROGRAM-ID.  likeatoi.
   DATA DIVISION.
   WORKING-STORAGE SECTION.
    01  the-char                                    PIC X 
                                          VALUE "K".
    01  the-result                                  PIC 999.
    01  the-other-result             BINARY         PIC 9(4) 
                                          VALUE ZERO.
    01  FILLER-1
    REDEFINES the-other-result. 
       05  FILLER                          PIC X.
       05  char-to-convert                 PIC X.

    01  the-comp-result              COMP           PIC 9(4)
                                          VALUE ZERO.
    01  FILLER-2
    REDEFINES the-comp-result. 
       05  FILLER                          PIC X.
       05  char-to-convert                 PIC X.

    01  the-packed-result            PACKED-DECIMAL PIC 9(4)
                                          VALUE ZERO.
    01  FILLER-3
    REDEFINES the-packed-result. 
       05  FILLER                          PIC X.
       05  char-to-convert                 PIC X.

    01 num                                 PIC 9(8).
    01 alfa                                PIC X(20)
       VALUE 'ABCDEFGHIJabcdefghij'.
    01 FILLER REDEFINES alfa.
        05 char                            PIC X OCCURS 20.
    01 w-index                             PIC 99 VALUE ZEROES.

   PROCEDURE DIVISION.
   MAINLINE.

       PERFORM VARYING w-index FROM 1 BY 1 UNTIL w-index > 20
           MOVE char(w-index)       TO the-char

  *        Variations of "Old School" code
           MOVE the-char            TO char-to-convert OF FILLER-1
           MOVE the-char            TO char-to-convert OF FILLER-2
           MOVE the-char            TO char-to-convert OF FILLER-3

           DISPLAY 
           ">"
           the-char
           "<"
           " with BINARY >"
           the-other-result
           "<"

           MOVE the-other-result       TO num
           DISPLAY "Numeric value: " num

           DISPLAY 
           ">"
           the-char
           "<"
           " with COMP >"
           the-comp-result
           "<"

           MOVE the-comp-result       TO num
           DISPLAY "Numeric value: " num

           DISPLAY 
           ">"
           the-char
           "<"
           " with PACKED >"
           the-packed-result
           "<"

           MOVE the-packed-result       TO num
           DISPLAY "Numeric value: " num
       END-PERFORM.

       STOP RUN.

而且,令我惊讶的是,它给了我这个输出

>A< with BINARY >A<

Numeric value: 00000065

>A< with COMP >A<

Numeric value: 00000100

(等等......)所以现在看起来它正在工作......可能是因为我第一次尝试使用的是 05-LEVEL 变量吗?

看起来已经完成了!

谢谢大家,Bill,你会在我的项目的问候部分找到答案的 :)

最后,一个细节。

如果我做出“移动”

MOVE 'A'     TO CHAR

然后做所有二进制的东西,结果不一样……这里举个例子。

VALUE,对于“D”,我得到 68,但对于 MOVE,我得到 60...

【问题讨论】:

  • 你需要更清楚。 HEX 只是一种符号,通常用于描述 ASCII 字符的位模式。那么......你能提供一些你真正想要的例子吗?
  • 您添加到问题中的标签应该是相关的。每个标签都有一个描述。如果描述与将搜索者带到您的问题的有用内容不匹配,它只会让人们抱怨标签的使用。它们不是“标签”。
  • 查看您的 COBOL 的文档。在内部函数中,您可能会找到您需要的东西。但这是一个猜测。
  • 我建议你再看看内在函数(第一次猜测)。由于您还没有得到它,请查看 FUNCTION ORD。
  • 看起来 ORD 可以工作。抱歉,我没有对内在函数给予足够的重视。

标签: hex cobol data-conversion


【解决方案1】:

您一直在为使用旧的编译器而苦恼。它符合 COBOL 85 标准,但不具备 1989 年标准扩展的内在功能。

此外,它还有一个我以前没有遇到过的非标准行为,这很难完全解释(无法访问该编译器)。

在 DISPLAY 中使用 > 和

因此,我建议使用 MOVE,然后在定义为 BINARY 时获得预期结果,在定义为 COMP 时获得......无法解释的结果。

对 COMP 结果的一种解释可能是 COMPUTATIONAL 字段完全由编译器实现者来定义。因此,一个系统上的 COMP 可能与另一个系统上的 COMP 类型不同(与 COMP-1、COMP-2、COMP-3 等相同)。这就是 1985 年标准引入新名称(例如 BINARY 和 PACKED-DECIMAL)的原因,以便它们可以跨 COBOL 编译器移植。

如果你坚持使用那个编译器,那你就很不幸。如果您有可能使用其他编译器,除了其他选择之外,您还可以找到开源 GnuCOBOL(我是 SourceForge.Net 上 GnuCOBOL 项目讨论区的主持人)。如果可以,请使用其他编译器。

这是一个示例程序,它将在现代 COBOL 编译器上运行,同时使用内部函数 ORD 和它曾经完成的方式(并且可能仍然完成)。请注意,如果您的 COMP 字段是“little endian”,请交换 FILLER 和 REDEFINES 下的字段的顺序。

   IDENTIFICATION DIVISION.
   PROGRAM-ID.  likeatoi.
   DATA DIVISION.
   WORKING-STORAGE SECTION.
   01  the-char                            PIC X 
                                              VALUE "A".
   01  the-result                          PIC 999.
   01  the-other-result             BINARY PIC 9(4) 
                                              VALUE ZERO.
   01  FILLER 
        REDEFINES the-other-result. 
       05  FILLER                          PIC X.
       05  char-to-convert                 PIC X.
   PROCEDURE DIVISION.
  *    with instrinsic function
       MOVE FUNCTION ORD ( the-char ) 
                                    TO the-result
       DISPLAY 
               ">"
               the-char
               "<"
               ">"
               the-result
               "<"

  *    Old School
       MOVE  the-char               TO char-to-convert
       DISPLAY 
               ">"
               the-char
               "<"
               ">"
               the-other-result
               "<"

       STOP RUN
       .

ORD 很简单,它实际上与 C 中的 atoi 相同(假设这为您提供了整理序列中的位置)。

在第二个中,由于 COBOL 传统上不能有一个单字节二进制文件,因此是一种使用 REDEFINES 获取双字节二进制文件低位部分的字符的方法,这样整个binary 字段表示该字符表示的“数值”。

上面的输出是:

>A<>066<
>A<>0065<

请注意,ORD 给出了整理序列中的 位置(带有 ORD 的二进制零将返回一),而第二个只是给出直接表示(二进制零将给出零)。

如果您只对可打印字符感兴趣,则要使用任一值,您可能需要在之后“重新设置”。

注意,我很困惑您有一个支持内联 PERFORM 但不支持内部函数的编译器。如果 BINARY 的 USAGE 被拒绝,请改用 COMP。

【讨论】:

  • 试过了,但正如我告诉你的,它失败了。尝试过的组合... COMP、COMP-3、BINARY... 最准确的是 PACKED-DECIMAL 与 PIC 9(2) PACKED-DECIMAL 一起使用,然后与 REDEFINES PIC S9(3) 一起使用。使用这种配置,对于“A”它给我“412”,对于“B”给我“422”等等。我看到前两个数字是正确的十六进制值,所以对我来说没问题,但是当我等待一种“4A”时,我得到“49”(也就是说,对于所有大于或等于“A”的数字,它出现一个“9”...
  • 能否将您正在使用的代码添加到您的问题中?
猜你喜欢
  • 2016-10-03
  • 2016-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-18
  • 2017-02-25
  • 1970-01-01
  • 2022-10-05
相关资源
最近更新 更多