I'll start by admitting this is for my homework and I don't expect anything specific just a tip perhaps. The input file is just one 30 byte field that contains names. The output file is two fields 30 bytes each. I'll list the code to show what I mean by this. The program needs to read the input file putting the names into an array and then print them to the two fields in the output file. It would be simple enough if the out put file was like this:
首先我得承认这是我的作业,我不期望有什么特别的东西,也许只是一个提示。输入文件只是一个包含名称的30字节字段。输出文件是两个字段,每个字段30字节。我将列出代码来说明我的意思。程序需要读取将名称放入数组的输入文件,然后将它们打印到输出文件中的两个字段。如果out put文件是这样的话就足够简单了:
name 1 name 2
name 3 name 4
etc...
but it's supposed to be:
但它应该是:
name 1 name 55
name 2 name 56
....
name 54 name 108
I'm not quite understanding how I can code the program to do this without having 54 lines of code (1 for each line in the output). Well here's the code I have so far:
我不太理解如何在没有54行代码(输出中的每一行都有1行代码)的情况下对程序进行编码。这是我到目前为止的代码:
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT NAMELIST-FILE-IN
ASSIGN TO 'NAMELIST.SEQ'
ORGANIZATION IS LINE SEQUENTIAL.
SELECT NAMELIST-FILE-OUT
ASSIGN TO 'NAMELIST.RPT'
ORGANIZATION IS LINE SEQUENTIAL.
DATA DIVISION.
FILE SECTION.
FD NAMELIST-FILE-IN.
01 NAME-IN PIC X(30).
FD NAMELIST-FILE-OUT.
01 NAME-OUT PIC X(60).
WORKING-STORAGE SECTION.
01 ARE-THERE-MORE-RECORDS PIC X(3) VALUE 'YES'.
01 PAGE-CTR PIC 99 VALUE ZERO.
01 SUB PIC 999 VALUE 1.
01 LEFT-NAME PIC 99 VALUE 54.
01 RIGHT-NAME PIC 9(3) VALUE 108.
01 WS-DATE.
05 RUN-YEAR PIC XX.
05 RUN-MONTH PIC XX.
05 RUN-DAY PIC XX.
01 HEADING-LINE.
05 PIC X(15) VALUE SPACES.
05 PIC X(20)
VALUE 'NAME LIST REPORT'.
05 HL-DATE.
10 DAY-HL PIC XX.
10 PIC X VALUE '/'.
10 MONTH-HL PIC XX.
10 PIC X VALUE '/'.
10 YEAR-HL PIC XX.
05 PIC X(3) VALUE SPACES.
05 PIC X(5) VALUE 'PAGE'.
05 PAGE-NUMBER-HL PIC Z9 VALUE 1.
01 DETAIL-LINE.
05 NAME-LEFT PIC X(30).
05 NAME-RIGHT PIC X(30).
01 NAME-ARRAY.
05 NAME-X OCCURS 108 PIC X(30).
PROCEDURE DIVISION.
100-MAIN.
OPEN INPUT NAMELIST-FILE-IN
OPEN OUTPUT NAMELIST-FILE-OUT
ACCEPT WS-DATE FROM DATE.
MOVE RUN-MONTH TO MONTH-HL
MOVE RUN-DAY TO DAY-HL
MOVE RUN-YEAR TO YEAR-HL
PERFORM 200-ACCEPT-INPUT
CLOSE NAMELIST-FILE-IN
CLOSE NAMELIST-FILE-OUT
STOP RUN.
200-ACCEPT-INPUT.
PERFORM UNTIL SUB > 108
READ NAMELIST-FILE-IN
MOVE NAME-IN TO NAME-X (SUB)
ADD 1 TO SUB
END-PERFORM
PERFORM 300-PRINT-ONE-PAGE.
300-PRINT-ONE-PAGE.
WRITE NAME-OUT FROM HEADING-LINE
AFTER ADVANCING PAGE
ADD 1 TO PAGE-CTR
Here's the final code for this program if anyone is interested in seeing it.
如果有人有兴趣的话,这是这个程序的最终代码。
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT NAMELIST-FILE-IN
ASSIGN TO 'NAMELIST.SEQ'
ORGANIZATION IS LINE SEQUENTIAL.
SELECT NAMELIST-FILE-OUT
ASSIGN TO 'NAMELIST.RPT'
ORGANIZATION IS LINE SEQUENTIAL.
DATA DIVISION.
FILE SECTION.
FD NAMELIST-FILE-IN.
01 NAME-IN PIC X(30).
FD NAMELIST-FILE-OUT.
01 NAME-OUT PIC X(80).
WORKING-STORAGE SECTION.
01 ARE-THERE-MORE-RECORDS PIC X(3) VALUE 'YES'.
01 PAGE-CTR PIC 99 VALUE ZERO.
01 SUB PIC 999.
01 SUB2 PIC 999.
01 LEFT-NAME PIC 99 VALUE 54.
01 RIGHT-NAME PIC 9(3) VALUE 108.
01 WS-DATE.
05 RUN-YEAR PIC XX.
05 RUN-MONTH PIC XX.
05 RUN-DAY PIC XX.
01 HEADING-LINE.
05 PIC X(26) VALUE SPACES.
05 PIC X(35)
VALUE 'NAME LIST REPORT'.
05 HL-DATE.
10 DAY-HL PIC XX.
10 PIC X VALUE '/'.
10 MONTH-HL PIC XX.
10 PIC X VALUE '/'.
10 YEAR-HL PIC XX.
05 PIC X(3) VALUE SPACES.
05 PIC X(5) VALUE 'PAGE'.
05 PAGE-NUMBER-HL PIC Z9.
01 DETAIL-LINE.
05 NAME-LEFT PIC X(40).
05 NAME-RIGHT PIC X(40).
01 NAME-ARRAY.
05 NAME-X OCCURS 108 PIC X(30).
PROCEDURE DIVISION.
100-MAIN.
OPEN INPUT NAMELIST-FILE-IN
OPEN OUTPUT NAMELIST-FILE-OUT
ACCEPT WS-DATE FROM DATE.
MOVE RUN-MONTH TO MONTH-HL
MOVE RUN-DAY TO DAY-HL
MOVE RUN-YEAR TO YEAR-HL
PERFORM UNTIL ARE-THERE-MORE-RECORDS = 'NO'
PERFORM 200-ACCEPT-INPUT
END-PERFORM
CLOSE NAMELIST-FILE-IN
CLOSE NAMELIST-FILE-OUT
STOP RUN.
200-ACCEPT-INPUT.
INITIALIZE NAME-ARRAY
MOVE 1 TO SUB
PERFORM UNTIL SUB > 108 OR ARE-THERE-MORE-RECORDS = 'NO'
READ NAMELIST-FILE-IN
AT END
MOVE 'NO' TO ARE-THERE-MORE-RECORDS
MOVE SPACES TO NAME-IN
END-READ
MOVE NAME-IN TO NAME-X (SUB)
ADD 1 TO SUB
END-PERFORM
PERFORM 300-PRINT-ONE-PAGE.
300-PRINT-ONE-PAGE.
ADD 1 TO PAGE-CTR
MOVE PAGE-CTR TO PAGE-NUMBER-HL
WRITE NAME-OUT FROM HEADING-LINE
AFTER ADVANCING PAGE
MOVE SPACES TO DETAIL-LINE
WRITE NAME-OUT FROM DETAIL-LINE
AFTER ADVANCING 1
PERFORM VARYING SUB FROM 1 BY 1 UNTIL SUB > 54
MOVE NAME-X (SUB) TO NAME-LEFT
COMPUTE SUB2 = SUB + 54
MOVE NAME-X (SUB2) TO NAME-RIGHT
WRITE NAME-OUT FROM DETAIL-LINE
AFTER ADVANCING 1
END-PERFORM.
2 个解决方案
#1
4
I must apologize, I cannot think of a way to guide you without giving away the answer. I guess this is a spoiler alert.
我必须道歉,我想不出一种方法来引导你而不给出答案。我猜这是剧透警告。
One possible method you could use would be to add a variable SUB2
to Working-Storage
and...
一种可能的方法是将变量SUB2添加到工作存储中,然后……
Perform Varying SUB From 1 By 1 Until SUB > 54
Move NAME-X(SUB) to NAME-LEFT
Compute SUB2 = SUB + 54
MOVE NAME-X(SUB2) to NAME-RIGHT
Write NAME-OUT from DETAIL-LINE After Advancing 1 Line
End-Perform
This is kind of kludgy and ties you to an array of 108 elements. You could use a record counter that you increment by 1 for each record read and then compute the values I show hardcoded in the sample above (54 is simply half of 108).
这是一种组装,将你连接到一个包含108个元素的数组。您可以使用一个记录计数器,对每次读取的记录增加1,然后计算我在上面的示例中显示的硬编码值(54只是108的一半)。
I don't show the page break logic, so perhaps I didn't give the whole show away.
我没有显示分页符的逻辑,所以可能我没有给出完整的显示。
I hope this helps you.
我希望这对你有帮助。
#2
1
I would have 2 arrays.
有两个数组。
One containing the whole file.
一个包含整个文件的文件。
01 DETAIL-LINE-ARRAY.
02 DETAIL-LINE OCCURS 54.
05 NAME-LEFT PIC X(30).
05 NAME-RIGHT PIC X(30).
Another like you did with NAME-ARRAY
另一个就像你用名字数组做的那样。
Then I would populate first the DETAIL-LINE-ARRAY
.
然后我将首先填充细节线数组。
I would read twice DETAIL-LINE-ARRAY to fill NAME-ARRAY
我将读取两次详细的线数组来填充名称数组
Then you can read sequentially NAME-ARRAY
然后可以读取顺序名称数组
==========================================================================
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Another solution:
另一个解决方案:
You can read the file twice. While the first read, you take care only of the left name and populate NAME-ARRAY
.
您可以读取该文件两次。在第一次读取时,只处理左名称并填充名称数组。
While the second reading, you take care only of the right name and continue to populate NAME-ARRAY
.
在第二次读取时,只处理正确的名称并继续填充名称数组。
After the first and second read, you can read your array NAME-ARRAY
.
在第一次和第二次读取之后,您可以读取数组名称数组。
==========================================================================
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
There is a problem with both last solutions : you have to know how much lines contains your file. Yep, you can have dynamic programming in cobol too :-)
最后两种解决方案都存在一个问题:您必须知道包含文件的行数。是的,您也可以用cobol进行动态编程:-)
You have to use SORT
.
你必须使用排序。
In FILE SECTION
add
在文件部分添加
SD SORT-WORK
01 SORT-RECORD.
05 SR-ORDER PIC 9(09).
05 SR-NAME PIC X(30).
In your PROCEDURE DIVISION
add (in pseude-code, you'll need to add some variables in your working storage section.
在过程分割中添加(在伪代码中,需要在工作存储部分中添加一些变量。
SORT SORT-WORK
ASCENDING SORT-ORDER
INPUT PROCEDURE IS 1000-INPUT
OUTPUT PROCEDURE IS 2000-OUTPUT
1000-INPUT SECTION.
MOVE 0 TO I.
PERFORM until end-of-file of NAMELIST-FILE-IN
ADD 1 TO I
READ left-name
MOVE I TO SORT-ORDER
MOVE left-name TO SR-NAME
* This operation populates the sort file...
RELEASE SORT-RECORD
END-PERFORM.
PERFORM until end-of-file of NAMELIST-FILE-IN
ADD 1 TO I
READ right-name
MOVE I TO SORT-ORDER
MOVE right-name TO SR-NAME
* This operation populates the sort file...
RELEASE SORT-RECORD
END-PERFORM.
MOVE I TO WS-NB-NAMES.
2000-OUTPUT SECTION.
PERFORM VARYING I FROM 1 BY 1 UNTIL I > WS-NB-NAMES
* This operation returns the "next" record. It begins by the first, second...
RETURN SORT-RECORD
MOVE SR-NAME TO NAME-LEFT
RETURN SORT-RECORD
MOVE SR-NAME TO NAME-RIGHT
WRITE NAMELIST-FILE-OUT FROM DETAIL-LINE
END-PERFORM.
You have some example here for SORT
这里有一些排序的例子
Have fun !
玩得开心!
#1
4
I must apologize, I cannot think of a way to guide you without giving away the answer. I guess this is a spoiler alert.
我必须道歉,我想不出一种方法来引导你而不给出答案。我猜这是剧透警告。
One possible method you could use would be to add a variable SUB2
to Working-Storage
and...
一种可能的方法是将变量SUB2添加到工作存储中,然后……
Perform Varying SUB From 1 By 1 Until SUB > 54
Move NAME-X(SUB) to NAME-LEFT
Compute SUB2 = SUB + 54
MOVE NAME-X(SUB2) to NAME-RIGHT
Write NAME-OUT from DETAIL-LINE After Advancing 1 Line
End-Perform
This is kind of kludgy and ties you to an array of 108 elements. You could use a record counter that you increment by 1 for each record read and then compute the values I show hardcoded in the sample above (54 is simply half of 108).
这是一种组装,将你连接到一个包含108个元素的数组。您可以使用一个记录计数器,对每次读取的记录增加1,然后计算我在上面的示例中显示的硬编码值(54只是108的一半)。
I don't show the page break logic, so perhaps I didn't give the whole show away.
我没有显示分页符的逻辑,所以可能我没有给出完整的显示。
I hope this helps you.
我希望这对你有帮助。
#2
1
I would have 2 arrays.
有两个数组。
One containing the whole file.
一个包含整个文件的文件。
01 DETAIL-LINE-ARRAY.
02 DETAIL-LINE OCCURS 54.
05 NAME-LEFT PIC X(30).
05 NAME-RIGHT PIC X(30).
Another like you did with NAME-ARRAY
另一个就像你用名字数组做的那样。
Then I would populate first the DETAIL-LINE-ARRAY
.
然后我将首先填充细节线数组。
I would read twice DETAIL-LINE-ARRAY to fill NAME-ARRAY
我将读取两次详细的线数组来填充名称数组
Then you can read sequentially NAME-ARRAY
然后可以读取顺序名称数组
==========================================================================
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Another solution:
另一个解决方案:
You can read the file twice. While the first read, you take care only of the left name and populate NAME-ARRAY
.
您可以读取该文件两次。在第一次读取时,只处理左名称并填充名称数组。
While the second reading, you take care only of the right name and continue to populate NAME-ARRAY
.
在第二次读取时,只处理正确的名称并继续填充名称数组。
After the first and second read, you can read your array NAME-ARRAY
.
在第一次和第二次读取之后,您可以读取数组名称数组。
==========================================================================
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
There is a problem with both last solutions : you have to know how much lines contains your file. Yep, you can have dynamic programming in cobol too :-)
最后两种解决方案都存在一个问题:您必须知道包含文件的行数。是的,您也可以用cobol进行动态编程:-)
You have to use SORT
.
你必须使用排序。
In FILE SECTION
add
在文件部分添加
SD SORT-WORK
01 SORT-RECORD.
05 SR-ORDER PIC 9(09).
05 SR-NAME PIC X(30).
In your PROCEDURE DIVISION
add (in pseude-code, you'll need to add some variables in your working storage section.
在过程分割中添加(在伪代码中,需要在工作存储部分中添加一些变量。
SORT SORT-WORK
ASCENDING SORT-ORDER
INPUT PROCEDURE IS 1000-INPUT
OUTPUT PROCEDURE IS 2000-OUTPUT
1000-INPUT SECTION.
MOVE 0 TO I.
PERFORM until end-of-file of NAMELIST-FILE-IN
ADD 1 TO I
READ left-name
MOVE I TO SORT-ORDER
MOVE left-name TO SR-NAME
* This operation populates the sort file...
RELEASE SORT-RECORD
END-PERFORM.
PERFORM until end-of-file of NAMELIST-FILE-IN
ADD 1 TO I
READ right-name
MOVE I TO SORT-ORDER
MOVE right-name TO SR-NAME
* This operation populates the sort file...
RELEASE SORT-RECORD
END-PERFORM.
MOVE I TO WS-NB-NAMES.
2000-OUTPUT SECTION.
PERFORM VARYING I FROM 1 BY 1 UNTIL I > WS-NB-NAMES
* This operation returns the "next" record. It begins by the first, second...
RETURN SORT-RECORD
MOVE SR-NAME TO NAME-LEFT
RETURN SORT-RECORD
MOVE SR-NAME TO NAME-RIGHT
WRITE NAMELIST-FILE-OUT FROM DETAIL-LINE
END-PERFORM.
You have some example here for SORT
这里有一些排序的例子
Have fun !
玩得开心!