COBOL问题-来自初学者的问题,请指导

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

我想做下面的事

pic X(5)的字符串包含A1992,并递增为A9999,在达到A9999后,a应替换为B,其他字符应重新初始化为0000 ie B0000,这应发生在Z9999之前,是否可能


或者,如果你能告诉我如何将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图表时错过了间隙。编辑是(更)可移植的。