COBOL问题-来自初学者的问题,请指导
我想做下面的事 pic X(5)的字符串包含A1992,并递增为A9999,在达到A9999后,a应替换为B,其他字符应重新初始化为0000 ie B0000,这应发生在Z9999之前,是否可能COBOL问题-来自初学者的问题,请指导,cobol,Cobol,我想做下面的事 pic X(5)的字符串包含A1992,并递增为A9999,在达到A9999后,a应替换为B,其他字符应重新初始化为0000 ie B0000,这应发生在Z9999之前,是否可能 或者,如果你能告诉我如何将A增加到Z,那就足够了,你需要在这个上面做一些手动字符操作。有几个部分,首先,您需要处理数字部分的简单相加,然后需要处理数字部分的滚动以增加字母部分 类似于此的数据结构可能会有所帮助: 01 Some-Work-Area. 02 Odometer-Char-Vals
或者,如果你能告诉我如何将A增加到Z,那就足够了,你需要在这个上面做一些手动字符操作。有几个部分,首先,您需要处理数字部分的简单相加,然后需要处理数字部分的滚动以增加字母部分 类似于此的数据结构可能会有所帮助:
01 Some-Work-Area.
02 Odometer-Char-Vals pic x(27) value 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.
02 Odometer-Char occurs 27 pic x.
02 Odo-Char-Ndx pic s9(8) binary.
01 My-Odometer.
88 End-Odometer-Value value 'Z9999'.
02 My-Odometer-X pic X.
02 My-Odometer-9 pic 9999.
88 Carry-Is-True value 9999.
这将与以下简单的执行循环一起使用:
Move 0 to My-Odometer-9
Move 1 to Odo-Char-Ndx
Move Odometer-Char-Vals (Odo-Char-Ndx) to My-Odometer-X
Perform until End-Odometer-Value
Add 1 to My-Odometer-9
Display My-Odometer
If Carry-Is-True
Move 0 to My-Odometer-9
Add 1 to Odo-Char-Ndx
Move Odometer-Char-Vals (Odo-Char-Ndx) to My-Odometer-X
End-If
End-Perform
这是你能做到的一种方法
请注意,上面的代码采用了一些快捷方式(又名skanky hacks)——比如在里程表字符数组中放置一个pad单元格,这样我就不必对其进行范围检查。除了例子和想法,你不会想用它来做任何事情 您需要在这一个上执行一些手动字符操作。有几个部分,首先,您需要处理数字部分的简单相加,然后需要处理数字部分的滚动以增加字母部分 类似于此的数据结构可能会有所帮助:
01 Some-Work-Area.
02 Odometer-Char-Vals pic x(27) value 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.
02 Odometer-Char occurs 27 pic x.
02 Odo-Char-Ndx pic s9(8) binary.
01 My-Odometer.
88 End-Odometer-Value value 'Z9999'.
02 My-Odometer-X pic X.
02 My-Odometer-9 pic 9999.
88 Carry-Is-True value 9999.
这将与以下简单的执行循环一起使用:
Move 0 to My-Odometer-9
Move 1 to Odo-Char-Ndx
Move Odometer-Char-Vals (Odo-Char-Ndx) to My-Odometer-X
Perform until End-Odometer-Value
Add 1 to My-Odometer-9
Display My-Odometer
If Carry-Is-True
Move 0 to My-Odometer-9
Add 1 to Odo-Char-Ndx
Move Odometer-Char-Vals (Odo-Char-Ndx) to My-Odometer-X
End-If
End-Perform
这是你能做到的一种方法
请注意,上面的代码采用了一些快捷方式(又名skanky hacks)——比如在里程表字符数组中放置一个pad单元格,这样我就不必对其进行范围检查。除了例子和想法,你不会想用它来做任何事情 我可能会使用嵌套的perform循环来实现这一点 存储:
01 ws-counter-def
03 ws-counter-def-alpha-list pic x(27) value 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.
03 ws-counter-def-num pic 9(4) comp-3.
01 ws-counter redefines ws-counter-def
03 ws-counter-alpha occurs 27 times indexed by counter-idx pic x.
03 ws-counter-num pic 9(4) comp-3.
01 ws-variable
03 ws-variable-alpha pic X
03 ws-variable-num pic X(4).
程序:
Initialize counter-idx.
Move 1992 to ws-counter-num.
Perform varying counter-idx from 1 by 1 until counter-idx > 26
move ws-counter-alpha(counter-idx) to ws-variable-alpha
perform until ws-counter-num = 9999
add 1 to ws-counter-
move ws-counter-num to ws-variable-num.
*do whatever it is you need to do to the pic X(5) value in ws-variable*
end-perform
move zeros to ws-counter-num
end-perform.
我可能会使用嵌套的perform循环来实现这一点 存储:
01 ws-counter-def
03 ws-counter-def-alpha-list pic x(27) value 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.
03 ws-counter-def-num pic 9(4) comp-3.
01 ws-counter redefines ws-counter-def
03 ws-counter-alpha occurs 27 times indexed by counter-idx pic x.
03 ws-counter-num pic 9(4) comp-3.
01 ws-variable
03 ws-variable-alpha pic X
03 ws-variable-num pic X(4).
程序:
Initialize counter-idx.
Move 1992 to ws-counter-num.
Perform varying counter-idx from 1 by 1 until counter-idx > 26
move ws-counter-alpha(counter-idx) to ws-variable-alpha
perform until ws-counter-num = 9999
add 1 to ws-counter-
move ws-counter-num to ws-variable-num.
*do whatever it is you need to do to the pic X(5) value in ws-variable*
end-perform
move zeros to ws-counter-num
end-perform.
我就是忍不住。。。这个怎么样
IDENTIFICATION DIVISION.
PROGRAM-ID. EXAMPLE.
DATA DIVISION.
WORKING-STORAGE SECTION.
01.
02 ALL-LETTERS PIC X(26) VALUE 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.
02 LETTERS REDEFINES ALL-LETTERS.
03 LETTER PIC X OCCURS 26 INDEXED BY I.
01 START-NUMBER PIC 9(4).
01 COUNTER.
02 COUNTER-LETTER PIC X.
02 COUNTER-NUMBER PIC 9(4).
PROCEDURE DIVISION.
MOVE 1992 TO START-NUMBER
PERFORM VARYING I FROM 1 BY 1 UNTIL I > LENGTH OF ALL-LETTERS
MOVE LETTER (I) TO COUNTER-LETTER
PERFORM TEST AFTER VARYING COUNTER-NUMBER FROM START-NUMBER BY 1
UNTIL COUNTER-NUMBER = 9999
DISPLAY COUNTER - or whatever else you need to do with the counter...
END-PERFORM
MOVE ZERO TO START-NUMBER
END-PERFORM
GOBACK
.
这将打印从A1992
到Z9999
的所有“数字”
基本上是偷了Marcus_33的代码,然后再把它翻了一点点。如果你这么想,请投他的答案,而不是我的我就是忍不住。。。这个怎么样
IDENTIFICATION DIVISION.
PROGRAM-ID. EXAMPLE.
DATA DIVISION.
WORKING-STORAGE SECTION.
01.
02 ALL-LETTERS PIC X(26) VALUE 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.
02 LETTERS REDEFINES ALL-LETTERS.
03 LETTER PIC X OCCURS 26 INDEXED BY I.
01 START-NUMBER PIC 9(4).
01 COUNTER.
02 COUNTER-LETTER PIC X.
02 COUNTER-NUMBER PIC 9(4).
PROCEDURE DIVISION.
MOVE 1992 TO START-NUMBER
PERFORM VARYING I FROM 1 BY 1 UNTIL I > LENGTH OF ALL-LETTERS
MOVE LETTER (I) TO COUNTER-LETTER
PERFORM TEST AFTER VARYING COUNTER-NUMBER FROM START-NUMBER BY 1
UNTIL COUNTER-NUMBER = 9999
DISPLAY COUNTER - or whatever else you need to do with the counter...
END-PERFORM
MOVE ZERO TO START-NUMBER
END-PERFORM
GOBACK
.
这将打印从A1992
到Z9999
的所有“数字”
基本上是偷了Marcus_33的代码,然后再把它翻了一点点。如果你觉得有这种倾向,请向上投票他的答案,而不是我的对于迷糊COBOL的爱好者来说,这是我能想到的最短(可移植)版本(假设编译器具有内在函数):
在OpenVMS/COBOL上测试。我将值缩短为X(3),因为看跑步很无聊。非便携版本(如果您知道平台的可用性)将前缀重新定义为
S9(4)COMP
,并直接递增低阶位。但是这个解决方案不会再短了…对于迷糊COBOL的爱好者来说,这里是我能想到的最短(可移植)版本(假设编译器具有内在函数):
在OpenVMS/COBOL上测试。我将值缩短为X(3),因为看跑步很无聊。非便携版本(如果您知道平台的可用性)将前缀重新定义为
S9(4)COMP
,并直接递增低阶位。但是这个解决方案不会再短了……两个小的改进:1)将外循环的UNTIL-phase更改为:…UNTIL-counter-idx>26
2)因为counter-idx
在内循环中从不更改,所以将移动ws-counter-alpha(counter-idx)…
放在内循环的正上方。哦,是的,两个都很好。我已经更改了我的帖子以包含您的更改。两个小的改进:1)将外循环的UNTIL-phase更改为:…UNTIL-counter-idx>26
2)由于counter-idx
从不在内循环中更改,请将移动ws-counter-alpha(counter-idx).
放在内循环的正上方。哦,是的,两个都很好。我已更改帖子以包含您的更改。看起来您的代码从?0001
开始,其中?
是下一个字母。OP要求每个字母从?0000开始。如果在Add 1…
之前移动了Display My Odomoter
,则打印的序列将以?0000
开始,但从不打印Z9999
。也许再仔细想想这一点……只要稍加调整,就行了!但是代码的编写方式简单而流畅。。我喜欢这种方式!看起来您的代码从?0001
开始,其中?
是下一个字母。OP要求每个字母从?0000开始。如果在Add 1…
之前移动了Display My Odomoter
,则打印的序列将以?0000
开始,但从不打印Z9999
。也许再仔细想想这一点……只要稍加调整,就行了!但是代码的编写方式简单而流畅。。我喜欢这种方式!您的代码不可移植。它假设CHAR(ORD(SOME-LETTER)+1)给出了字母表中的下一个字母。这可能适用于ASCII字符集,但对于某些其他字符集则完全错误。例如:CHAR(ORD('I')+1)在EBCDIC字符集中不是“J”。@NealB:谢谢,我在扫描EBCDIC图表时错过了间隙。编辑是(更)可移植的。您的代码是不可移植的。它假设CHAR(ORD(SOME-LETTER)+1)给出了字母表中的下一个字母。这可能适用于ASCII字符集,但对于某些其他字符集则完全错误。例如:CHAR(ORD('I')+1)在EBCDIC字符集中不是“J”。@NealB:谢谢,我在扫描EBCDIC图表时错过了间隙。编辑是(更)可移植的。