如何编写cobol代码来执行以下逻辑?

时间:2016-06-06 10:40:29

标签: cobol

1)读取一行2000个字符并用一个" +"替换所有空格。加上性格。即将"A B"转换为"A+B""A B"转换为"A+B"

2)读取一行2000个字符,然后搜索特定模式,如" PWD"或" INI"或者等等,最后将6个字符存储到变量中。

3)读取一行2000个字符,并将字符串中的最后一个字存储到变量中。

编辑: 我使用Micro Focus COBOL。

This是我目前为止的代码截图。

我的代码如下。它删除了一些空格,但不是全部。尝试在单词和输入文件之间用任意数量的空格来编写测试数据。

   IDENTIFICATION DIVISION.
   PROGRAM-ID. SALAUT.
   ENVIRONMENT DIVISION.
    FILE-CONTROL.
     SELECT IN-FILE ASSIGN TO "INFILE"
            ORGANIZATION IS LINE SEQUENTIAL
            FILE STATUS IS WS-IN-FILE-STATUS.
     SELECT OUT-FILE ASSIGN TO "OUTFILE"
            ORGANIZATION IS LINE SEQUENTIAL
            FILE STATUS IS WS-OUT-FILE-STATUS.
   DATA DIVISION.
   FILE SECTION.
   FD IN-FILE.
   01 FS-IN-FILE                           PIC X(200).
   FD OUT-FILE.
   01 FS-OUT-FILE                          PIC X(200).
    WORKING-STORAGE SECTION.
       01 WS-ATMA-C.
         03 WS-OUT-FILE-STATUS       PIC X(02).
         03 WS-IN-FILE-STATUS        PIC X(02).
         03 WS-LOOP-COUNTER          PIC 9(03) VALUE 1.
         03 WS-IN-EOF                PIC X value 'N'.
         03 WS-IN-FILE-LEN           PIC 9(03).
         03 WS-IN-SPACE-CNT          PIC 9(03) VALUE 1. 
         03 FS-IN-FILE-2             PIC X(200).
         03 WS-TRIL-SPACE-CNT        PIC 9(03).
         03 WS-TOT-SPACE-CNT         PIC 9(03). 
   PROCEDURE DIVISION.
   MAIN-PARA.     
        OPEN INPUT IN-FILE.
        IF WS-IN-FILE-STATUS <> '00'
         EXHIBIT 'IN-FILE-OPEN-ERROR : STOP-RUN'
         EXHIBIT NAMED WS-IN-FILE-STATUS
         PERFORM MAIN-PARA-EXIT
        END-IF.
        OPEN OUTPUT OUT-FILE.
        IF WS-OUT-FILE-STATUS <> '00'
         EXHIBIT 'OUT-FILE-OPEN-ERROR : STOP-RUN'
         EXHIBIT NAMED WS-OUT-FILE-STATUS
         PERFORM MAIN-PARA-EXIT
        END-IF.

        PERFORM SPACE-REMOVER-PARA THRU SPACE-REMOVER-PARA-EXIT.

         CLOSE IN-FILE.
         IF WS-IN-FILE-STATUS <> '00'
          EXHIBIT 'IN-FILE-CLOSE-ERROR : STOP-RUN'
          EXHIBIT NAMED WS-IN-FILE-STATUS
          PERFORM MAIN-PARA-EXIT
         END-IF.
        CLOSE OUT-FILE.
        IF WS-OUT-FILE-STATUS <> '00'
         EXHIBIT 'IN-FILE-CLOSE-ERROR : STOP-RUN'
         EXHIBIT NAMED WS-OUT-FILE-STATUS
         PERFORM MAIN-PARA-EXIT
        END-IF.
   MAIN-PARA-EXIT.
      STOP RUN.
   SPACE-REMOVER-PARA.
    PERFORM UNTIL WS-IN-EOF = 'Y'
    INITIALIZE FS-IN-FILE FS-OUT-FILE WS-IN-FILE-LEN FS-IN-FILE-2
    READ IN-FILE 
     AT END 
      MOVE 'Y' TO WS-IN-EOF 
     NOT AT END
      INSPECT FS-IN-FILE TALLYING WS-IN-FILE-LEN FOR CHARACTERS
      EXHIBIT NAMED WS-IN-FILE-LEN
      MOVE 1 TO WS-LOOP-COUNTER
      IF WS-IN-FILE-LEN <> 0
       PERFORM UNTIL WS-IN-SPACE-CNT <= ZEROS 
       INSPECT FS-IN-FILE TALLYING WS-TOT-SPACE-CNT FOR ALL "  "
       INSPECT FUNCTION REVERSE (FS-IN-FILE) TALLYING 
                    WS-TRIL-SPACE-CNT FOR LEADING "  "
       INITIALIZE WS-IN-SPACE-CNT
       COMPUTE WS-IN-SPACE-CNT = 
                    WS-TOT-SPACE-CNT - WS-TRIL-SPACE-CNT
       PERFORM VARYING WS-LOOP-COUNTER FROM 1 BY 1
          UNTIL WS-LOOP-COUNTER >=
                WS-IN-FILE-LEN - (2 * WS-TRIL-SPACE-CNT) 
        IF FS-IN-FILE(WS-LOOP-COUNTER:2) = "  "
         STRING FS-IN-FILE(1:WS-LOOP-COUNTER - 1) DELIMITED BY SIZE
                FS-IN-FILE(WS-LOOP-COUNTER + 2
                           : WS-IN-FILE-LEN - WS-LOOP-COUNTER - 2)
                                              DELIMITED BY SIZE
                INTO FS-IN-FILE-2
         END-STRING
         INITIALIZE FS-IN-FILE 
         MOVE FS-IN-FILE-2 TO FS-IN-FILE
         INITIALIZE FS-IN-FILE-2
        END-IF
       END-PERFORM
       INITIALIZE WS-LOOP-COUNTER WS-TRIL-SPACE-CNT WS-TOT-SPACE-CNT
       END-PERFORM
       WRITE FS-OUT-FILE FROM FS-IN-FILE
       IF WS-OUT-FILE-STATUS <> '00'
        EXHIBIT 'OUT-FILE-WRITE-ERROR : STOP-RUN'
        EXHIBIT NAMED WS-OUT-FILE-STATUS
        PERFORM MAIN-PARA-EXIT
       END-IF
      END-IF
    END-READ
    END-PERFORM.
   SPACE-REMOVER-PARA-EXIT.
        EXIT.

2 个答案:

答案 0 :(得分:2)

由于FUNCTION SUBSTITUTE仅允许替换不能使用它的相同数量的字节。正如Brian指出的那样,你的COBOL运行时可能会附带像GnuCOBOL&{39} UNSTRING这样的选项。在任何情况下问题&#34;哪个COBOL&#34;仍然有用回答。

要做Thraydor的方法,请使用字符串指针将MOVE 1 TO strpoint PERFORM VARYING table-idx FROM 1 BY 1 UNTIL table-idx = table-max UNSTRING your2000line DELIMITED BY ALL SPACES INTO tmp-table (table-idx) WITH POINTER strpoint NOT ON OVERFLOW EXIT PERFORM END-UNSTRING END-PERFORM 用于表。

PERFORM

另一种始终有效的方法是在2000字节上使用简单的IF your2000line (pos:1),并使用一堆EVALUATE语句(如果可能:将它组合到单个MOVE)逐字节检查(比较用于删除重复字节的最后一个字节)将带有替换的源转移到临时字段,并在完成后将其{{1}}移回

请修改您的问题以显示您的确切尝试,并获得更好的答案。

答案 1 :(得分:1)

首先,请记住COBOL是一种方言语言。还有一些活跃的商业编译器,其目标是1974年,1985年,2002年(现已过时,2014年并入)和2014年标准。所有这些都有自己的语言扩展,在不同的COBOL编译器中可能会或许多都不会被尊重。

如果您的学习目标是特定环境(您所说的IBM大型机COBOL),那么请将该方言用作您正在使用的实际COBOL中可用的部分。这意味着使用IBM手册。

不要从地方挑选东西并使用它只是因为它在某种程度上似乎是一个好主意。

我不得不承认,EXHIBIT使用起来非常有趣,但它只是一个语言扩展,并且IBM至少在OS / VS COBOL的后期版本中删除了它。和ON一样,它是一个&#34;调试&#34;声明,虽然这并没有阻止他们被使用&#34;通常&#34;。在简单的DISPLAY上使用EXHIBIT需要额外的开销。 IBM Enterprise COBOL只有一个简单的DISPLAY。

虽然你可能觉得使用象形图很有趣(#34;哦,我的天哪,我应该使用什么符号来表示这个&#34;一个试图拔掉自己头发的人物)要注意那个特殊的符号是2014标准的后来者,如果它在未来20到50年内出现在企业COBOL中,我会感到惊讶(要做的事情很少,另一种可爱的写作方式&#34;不等于to&#34;当许多已经存在时,COBOL甚至有一个ELSE)。

一些指示。没有一个名为&#34;删除所有空格&#34;的程序。如果它的作用本身就是&#34;一切 - 包括 - 安装一个新的厨房水槽&#34;。难道你无法找到它为什么不起作用吗?

许多很多很多COBOL程序都有读取文件的任务,直到最后,并处理文件中的记录。让自己成为第一个运作良好的人之一。这与业务流程有关吗?该计划正在解决?不,它只是技术性的东西,你不能没有所以不要把它隐藏在某个地方。哪里?在PERFORMed程序(段落或SECTIONS)。不要指望一个很快想知道你的程序正在做什么的人想要阅读每个程序所做的事情。隐藏它。

你可以在这里找到关于编写COBOL程序的一些一般性建议。注意那些建议使用全站/句号,启动读数和COBOL程序的一般结构的人。

准确描述事物非常重要。为数据名称和程序提供良好,描述性和准确的名称。文件是记录的集合。

您已缩减数据大小以简化测试,而无需在返回完整长度数据时发现数据定义存在问题。你的&#34;柜台&#34;当他们需要能够处理高达2000的数字时,他们只能容纳三位数。

对一段数据做某事毫无意义,然后立即用其他与原始内容无关的东西来压制某些东西。

MOVE SPACE TO B
MOVE A TO B

第一个MOVE是冗余的,超级的,除了吸收CPU时间并且混淆程序的下一个读者之外什么都不做。 &#34;是否缺少一些代码,因为否则这些代码很简单&#34;。

这是使用MOVE的该示例的变体,并且您在整个地方都这样做:

   INITIALIZE WS-IN-SPACE-CNT
   COMPUTE WS-IN-SPACE-CNT = 
                WS-TOT-SPACE-CNT - WS-TRIL-SPACE-CNT 

INITIALIZE浪费了空间,资源和混乱的介绍人,以及额外的代码行,使您的程序更难理解。

另外,不要重置&#34;使用它们之后的事情,以便它们为下一次做好准备&#34;。这会产生一个依赖关系,这是程序的未来发明者不会期望的。即使在预期/注意到的情况下,它们也会使代码更难以遵循。

如果不知道你认为错误的代码,你的代码究竟出了什么问题就不可能了。例如,甚至没有&#34; +&#34;替换任何空格,所以如果你觉得这是错的,你根本就没有为它编码。

您还尝试过三项任务中的一项。如果那些不工作的人就是你认为错的......

知道你认为错的是一回事,但还有很多其他问题。如果你坐下来,有条不紊地对它们进行分类,那么你就会在结构上提出一个&#34;&#34; COBOL程序,您会发现它更容易理解您自己的代码所做的事情以及问题所在。

A  B   C  D    E

A+B+C+D+E

要使用STRING从第一个到第二个,请查看Simon建议使用WITH POINTER。

您可以采用的另一种方法是使用引用修改。

无论哪种方式,您都可以一次构建一个结果字段

This field intentionally blank
A
A+B
A+B+C
A+B+C+D
A+B+C+D+E

而不是每次都扔掉所有数据。还有其他方法可以对其进行编码,但这可以在以后进行。