我正在寻找一种将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
,如:< / p>
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.
现在,这里是我尝试的所有细节:
首先,尝试使用INTRINSIC FUNCTION ORD编译它:
***** 1) 0384: E User-defined word expected instead of reserved word. (scan su
使用此编译,运行程序(忽略错误):
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.
Errors: 0, Warnings: 1, Lines: 37 for program LIKEATOI.
(显示COMP变量的警告,没关系)
再次执行(没有“num”,仍然使用comp变量):
>A<> <
>A<>A<
添加“num”变量,将char更改为“K”并将COMP更改为PACKED-DECIMAL(HEX:4B)
>K<> <
>K<>K<
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变量?
现在看来已经完成了!
感谢大家,比尔,你会看到我项目的问候部分:)
最后,一个细节。
如果我进行“移动”
MOVE 'A' TO CHAR
然后做所有二进制的东西,结果是不同的...这里是一个例子。
VALUE
,“D”我得68,但是MOVE
我得到60 ......
答案 0 :(得分:2)
您一直在使用旧的编译器。符合COBOL 85标准,但不具备1989年标准扩展的内在功能。
此外,它还具有我之前未遇到的非标准行为,这很难完全解释(无法访问该编译器)。
使用&gt;的要点和&lt;在DISPLAY中,您始终可以确切知道每个输出字段的长度。您知道是否有空白或某些不可打印的字符。您定义为COMP和BINARY的字段显示只显示一个字符,而不是四个数字,通常保存在两个存储字节中(如INT,但限制为9999)。
因此,我建议使用MOVE,然后在定义为BINARY时获得预期结果,并在定义为COMP时获得无法解释的结果。
对COMP结果的一种解释可能是COMPUTATIONAL字段完全由编译器实现者来定义。因此,在一个系统上什么是COMP可能与另一个系统上的COMP不是相同类型的场(与COMP-1,COMP-2,COMP-3 etC相同)。这就是1985年标准引入新名称(例如BINARY和PACKED-DECIMAL)的原因,以便它们可以在COBOL编译器中移植。
如果你坚持使用该编译器,那你很不幸。如果您有可能使用其他编译器,您可以在其他选项中找到开源GnuCOBOL(我是SourceForge.Net上GnuCOBOL项目讨论区的主持人)。如果可以,请使用其他编译器。
这是一个示例程序,它将使用内部函数ORD和它以前完成的方式(可能仍然完成)在现代COBOL编译器上工作。请注意,如果您的COMP字段是“little endian”,请在REDEFINES下交换FILLER和字段的顺序。
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来获取一个双字节二进制文件的低位部分的字符,这样就可以了二进制字段表示该字符表示的“数值”。
以上的输出是:
>A<>066<
>A<>0065<
请注意,ORD在整理顺序中给出位置(ORD的二进制零将返回一个),第二个只是给出直接表示(二进制零将给零)。
要使用任何一个值,如果您只对可打印字符感兴趣,则可能需要在之后“重新定位”。
注意,我很困惑你有一个支持内联PERFORM但不支持内部函数的编译器。如果拒绝使用BINARY,请改用COMP。