Getting "mismatched input '>' expecting {<EOF>, IDENTIFICATION, REPLACE}" when trying to run COBOL code - cobol

COMPLETE NOOB here just trying to learn some COBOL. I'm following a YT video and the code I have written verbatim just won't run because of this error. Do I need to install another extension?
>>SOURCE FORMAT FREE
IDENTIFICATION DIVISION.
PROGRAM-ID. coboltut.
AUTHOR. John Doe.
DATE-WRITTEN. November 24th 2021
ENVIRONMENT DIVISION.
DATA DIVISION.
FILE SECTION.
WORKING-STORAGE SECTION.
01 UserName PIC X(30) VALUE "You".
01 Num1 PIC 9 VALUE ZEROS.
01 Num2 PIC 9 VALUE ZEROS.
01 Total PIC 99 VALUE 0.
01 SSNum.
02 SSArea PIC 999
03 SSGroup PIC 99
03 SSSerial PIC 9999
PROCEDURE DIVISION.
DISPLAY "WHAT IS YOUR NAME " WITH NO ADVANCING
ACCEPT UserName
DISPLAY "Hello " USERNAME
STOP RUN.

Try this:
$ cat coboltut.cbl
IDENTIFICATION DIVISION.
PROGRAM-ID. coboltut.
AUTHOR. John Doe.
DATE-WRITTEN. November 24th 2021
ENVIRONMENT DIVISION.
DATA DIVISION.
FILE SECTION.
WORKING-STORAGE SECTION.
01 UserName PIC X(30) VALUE "You".
01 Num1 PIC 9 VALUE ZEROS.
01 Num2 PIC 9 VALUE ZEROS.
01 Total PIC 99 VALUE ZEROS.
01 SSNum.
03 SSArea PIC 999.
03 SSGroup PIC 99.
03 SSSerial PIC 9999.
PROCEDURE DIVISION.
DISPLAY "WHAT IS YOUR NAME " WITH NO ADVANCING
ACCEPT UserName
DISPLAY "Hello " USERNAME
STOP RUN.
Execution:
$ cobc -F -x coboltut.cbl
$ ./coboltut
WHAT IS YOUR NAME Halley
Hello Halley

Related

OpenCOBOL can't find my external module to run the program

I'm trying to create a COBOL program using OpenCobol that has an external module when it does a calculation and then brings the result back into the main program using CALL. But everytime I try to run the program it says it can't find the module. I have already changed my module to Program Type "Module" from executable and I have added the module path as a Library path but nothing is working so far
Here is my main program code:
PROGRAM-ID. Project2 AS "Project2".
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
*****The student input file
SELECT STUDENT-FILE-IN
ASSIGN TO "C:\STUFILE.TXT"
ORGANIZATION IS LINE SEQUENTIAL.
*****The program input file
SELECT PROGRAM-FILE-IN
ASSIGN TO "C:\PROGRAM.TXT"
ORGANIZATION IS LINE SEQUENTIAL.
*****The student report output file
SELECT STUDENT-REPORT-FILE-OUT
ASSIGN TO "C:\REPORT.TXT"
ORGANIZATION IS LINE SEQUENTIAL.
DATA DIVISION.
FILE SECTION.
*Student input file
FD STUDENT-FILE-IN.
01 STUDENT-RECORD.
05 STUDENT-NUMBER PIC 9(6).
05 TUITION-OWED-IN PIC 9(4)V99.
05 STUDENT-NAME-IN PIC X(40).
05 PROGRAM-OF-STUDY PIC X(5).
05 COURSE-CODE-1 PIC X(7).
05 COURSE-AVERAGE-1 PIC 9(3).
05 COURSE-CODE-2 PIC X(7).
05 COURSE-AVERAGE-2 PIC 9(3).
05 COURSE-CODE-3 PIC X(7).
05 COURSE-AVERAGE-3 PIC 9(3).
05 COURSE-CODE-4 PIC X(7).
05 COURSE-AVERAGE-4 PIC 9(3).
05 COURSE-CODE-5 PIC X(7).
05 COURSE-AVERAGE-5 PIC 9(3).
*Program input file
FD PROGRAM-FILE-IN.
01 PROGRAM-RECORD-IN.
05 PROGRAM-CODE-IN PIC X(5).
05 PROGRAM-NAME-IN PIC X(20).
*Student report output file
FD STUDENT-REPORT-FILE-OUT.
01 STUDENT-REPORT-RECORD-OUT PIC x(90).
WORKING-STORAGE SECTION.
*Table to hold program records
01 PROGRAM-RECORD.
05 PROGRAM-TABLE.
10 PROGRAM-CODE PIC X(5) OCCURS 20 TIMES.
10 PROGRAM-NAME PIC X(20) OCCURS 20 TIMES.
*The student report record
01 STUDENT-REPORT-RECORD.
05 STUDENT-NAME PIC X(40).
05 FILLER PIC X(2) VALUE SPACES.
05 PROGRAM-NAME-OUT PIC X(20).
05 FILLER PIC X(4) VALUE SPACES.
05 TUITION-OWED PIC Z,ZZ9.99.
*A line to make the output look good
01 HEADER-LINE.
05 FILLER PIC X(90) VALUE ALL "-".
*The column header
01 COLUMN-HEADER.
05 NAME-COLUMN PIC X(42) VALUE "NAME".
05 AVG-COLUMN PIC X(7) VALUE "AVE".
05 PROG-COLUMN PIC X(24) VALUE "PROGRAM NAME".
05 OWED-COLUMN PIC X(12) VALUE "TUITION OWED".
01 CONTROL-FIELDS.
05 STUFILE-EOF-FLAG PIC A(3).
05 PROG-EOF-FLAG PIC A(3).
05 PROG-SUB PIC 9(2).
05 FOUND-PROG-FLAG PIC A(3).
01 COUNTERS.
05 STUDENT-RECORDS-READ-CTR PIC 9(3).
05 STUDENT-REPORTS-WRITTEN-CTR PIC 9(3).
01 WW-SEND-AREA.
05 STUDENT-AVERAGE PIC 9(3).
01 WW-SUB-PROG PIC X(75)
VALUE 'C:\Users\google\Program3Call'.
PROCEDURE DIVISION.
PERFORM 200-INITIALIZATION-RTN.
*Read and process all student records
PERFORM 200-PROCESS-STUDENT-RECORD-RTN
UNTIL STUFILE-EOF-FLAG = "YES".
PERFORM 200-FINISH-RTN.
STOP RUN.
200-INITIALIZATION-RTN.
PERFORM 300-OPEN-FILES-RTN.
*****Load all program records into the table
PERFORM 300-LOAD-PROGRAM-TABLE-RTN
VARYING PROG-SUB FROM 1 BY 1
UNTIL PROG-SUB > 20 OR PROG-EOF-FLAG = "YES".
PERFORM 300-INITIALIZE-REPORT-FILE-RTN.
PERFORM 300-INITIALIZE-COUNTERS-RTN.
200-PROCESS-STUDENT-RECORD-RTN.
PERFORM 300-READ-STUDENT-RECORD-RTN.
IF STUFILE-EOF-FLAG NOT EQUALS "YES"
*********Get the program name
PERFORM 300-GET-PROGRAM-NAME-RTN
VARYING PROG-SUB FROM 1 BY 1 UNTIL
FOUND-PROG-FLAG = "YES" OR PROG-SUB > 20
PERFORM 300-GET-STUDENT-AVERAGE
PERFORM 300-PRINT-STUDENT-REPORT-RTN
END-IF.
200-FINISH-RTN.
PERFORM 300-PRINT-COUNTERS-RTN.
PERFORM 300-CLOSE-FILES-RTN.
300-OPEN-FILES-RTN.
OPEN INPUT STUDENT-FILE-IN.
OPEN INPUT PROGRAM-FILE-IN.
OPEN OUTPUT STUDENT-REPORT-FILE-OUT.
300-LOAD-PROGRAM-TABLE-RTN.
READ PROGRAM-FILE-IN
AT END MOVE "YES" TO PROG-EOF-FLAG
NOT AT END MOVE PROGRAM-CODE-IN TO PROGRAM-CODE (PROG-SUB)
MOVE PROGRAM-NAME-IN TO PROGRAM-NAME (PROG-SUB).
300-INITIALIZE-REPORT-FILE-RTN.
MOVE COLUMN-HEADER TO STUDENT-REPORT-RECORD-OUT.
WRITE STUDENT-REPORT-RECORD-OUT.
MOVE HEADER-LINE TO STUDENT-REPORT-RECORD-OUT.
WRITE STUDENT-REPORT-RECORD-OUT.
300-INITIALIZE-COUNTERS-RTN.
MOVE 0 TO STUDENT-RECORDS-READ-CTR.
MOVE 0 TO STUDENT-REPORTS-WRITTEN-CTR.
300-READ-STUDENT-RECORD-RTN.
READ STUDENT-FILE-IN
AT END MOVE "YES" TO STUFILE-EOF-FLAG
NOT AT END ADD 1 TO STUDENT-RECORDS-READ-CTR.
300-GET-PROGRAM-NAME-RTN.
IF PROGRAM-CODE (PROG-SUB) = PROGRAM-OF-STUDY
MOVE PROGRAM-NAME (PROG-SUB) TO PROGRAM-NAME-OUT
MOVE "YES" TO FOUND-PROG-FLAG
END-IF.
300-GET-STUDENT-AVERAGE.
CALL WW-SUB-PROG USING WW-SEND-AREA.
300-PRINT-STUDENT-REPORT-RTN.
MOVE "NO" TO FOUND-PROG-FLAG.
MOVE STUDENT-NAME-IN TO STUDENT-NAME.
MOVE TUITION-OWED-IN TO TUITION-OWED.
MOVE STUDENT-REPORT-RECORD TO STUDENT-REPORT-RECORD-OUT.
WRITE STUDENT-REPORT-RECORD-OUT.
ADD 1 TO STUDENT-REPORTS-WRITTEN-CTR.
300-PRINT-COUNTERS-RTN.
DISPLAY "Student records read: ", STUDENT-RECORDS-READ-CTR.
DISPLAY "Student reports written: ",
STUDENT-REPORTS-WRITTEN-CTR.
300-CLOSE-FILES-RTN.
CLOSE STUDENT-FILE-IN, PROGRAM-FILE-IN
STUDENT-REPORT-FILE-OUT.
END PROGRAM Project2.
Here is my Call Program:
******************************************************************
* Author: Desiree Hanuman
* Date: August 14th 2021
* Purpose:Call Section code for project 3
* Tectonics: cobc
******************************************************************
IDENTIFICATION DIVISION.
PROGRAM-ID. Program3Call.
DATA DIVISION.
LINKAGE SECTION.
01 LS-STUDENT-AVERAGE-AREA.
05 COURSE-AVERAGE-1 PIC 9(3).
05 COURSE-AVERAGE-2 PIC 9(3).
05 COURSE-AVERAGE-3 PIC 9(3).
05 COURSE-AVERAGE-4 PIC 9(3).
05 COURSE-AVERAGE-5 PIC 9(3).
05 STUDENT-AVERAGE PIC 9(3).
PROCEDURE DIVISION.
MAIN-PROCEDURE.
100-STUDENT-AVERAGE.
PERFORM 300-CALCULATE-AVERAGE-RTN.
300-CALCULATE-AVERAGE-RTN.
COMPUTE STUDENT-AVERAGE ROUNDED = (COURSE-AVERAGE-1 +
COURSE-AVERAGE-2 + COURSE-AVERAGE-3 + COURSE-AVERAGE-4 +
COURSE-AVERAGE-5) / 5.
GOBACK.
The normal way to CALL in most COBOL implementations is to just specify the module name - without a path or extension.
Then you either do "static linking" (as in Scott's answer below for OpenCOBOL/GnuCOBOL just specify all sources on the command line and use either -x [fat executable] or -b [fat module, then callable for example with cobcrun], commonly with -static); or do "dynamic linking" (separate compilation of all modules) and specify the module path in a configuration file or by environment variable. For OpenCOBOL/GnuCOBOL this is COB_LIBRARY_PATH.
I am not a user of OpenCobol, but, according to their manual in section 7, there are many ways to accomplish what you want.
But the simplest would be to statically compile and link the main and sub programs in one command line:
cobc -x Project2.cbl Program3Call.cbl
This example work´s for me.
Please keep in mind that the name of the dll file routine module must be same as the routine name.
It is not necessary reconfigure OpenCobol path library.
I use OpenCobol 4.7.6.
The Code:
Main program (file build "MAINPROG.exe")
IDENTIFICATION DIVISION.
PROGRAM-ID. "MAINPROG".
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 X PIC X(1).
01 INPUTS.
05 PRM-LENGTH PIC S9(4) COMP.
05 INPUT1 PIC 9(2).
05 INPUT2 PIC 9(2).
PROCEDURE DIVISION.
MAIN-PARA.
MOVE 12 TO INPUT1.
MOVE 13 TO INPUT2.
CALL 'MFPROG1' USING PRM-LENGTH, INPUT1, INPUT2.
ACCEPT X.
STOP RUN.
END PROGRAM "MAINPROG".
Rutine program (file build module "MFPROG1.dll")
IDENTIFICATION DIVISION.
PROGRAM-ID. "MFPROG1".
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 OUTPUT-DATA PIC 9(4).
LINKAGE SECTION.
01 PARM-BUFFER.
05 PARM-LENGTH PIC S9(4) COMP.
05 PARM-INPUT1 PIC 9(2).
05 PARM-INPUT2 PIC 9(2).
PROCEDURE DIVISION USING PARM-BUFFER.
MAIN-PARA.
COMPUTE OUTPUT-DATA = PARM-INPUT1 + PARM-INPUT2.
DISPLAY 'PARM-INPUT1: ' PARM-INPUT1.
DISPLAY 'PARM-INPUT2: ' PARM-INPUT2.
DISPLAY 'SUM VALUE : ' OUTPUT-DATA.
GOBACK.
END PROGRAM "MFPROG1".

How does COBOL actually accept numeric values?

I have a very simple COBOL code here that has a given input data and output data. The problem is that, it shows an error on line 60 which is the MOVE STUD-AGE TO AGE-OUT. and everytime I run OpenCOBOLIDE, I always get and error which is:
libcob: test.cob: 60: 'STUD-AGE' not numeric: ' '
WARNING - Implicit CLOSE of STUDENT-OUT ('C:\STUD-OUT.DAT')
WARNING - Implicit CLOSE of STUDENT-IN ('C:\STUD-IN.DAT')
And I don't know exactly what's wrong with it. Here is supposedly the input file I created:
----5---10---15---20---25---30---35---40--
00-123345 ALISON MARTIN WOLF 1912056
00-789012 KEN DENNIOS ROME 1914156
00-345678 JACK ADRIAN TOCKSIN 1622234
00-901234 EJHAYZ ALONEY 2045645
00-567890 CHARLES JOHN GUINNIVER 1813243
00-123457 JEAN MICHAEL YARTER 2034253
Here's the code to it:
IDENTIFICATION DIVISION.
PROGRAM-ID. SAMPLE.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT STUDENT-IN ASSIGN TO "C:\STUD-IN.DAT".
SELECT STUDENT-OUT ASSIGN TO "C:\STUD-OUT.DAT".
DATA DIVISION.
FILE SECTION.
FD STUDENT-IN.
01 STUD-REC.
02 STUD-NO PIC X(10).
02 STUD-NAME PIC X(25).
02 STUD-AGE PIC 99.
02 STUD-ALLOWANCE PIC 999V99.
FD STUDENT-OUT.
01 PRINT-REC PIC X(80).
WORKING-STORAGE SECTION.
01 HDG-1.
02 FILLER PIC X(20) VALUE SPACES.
02 FILLER PIC X(22) VALUE "WILLOW PARK UNIVERSITY".
02 FILLER PIC X(14) VALUE " OF MADAGASCAR".
01 HDG-2.
02 FILLER PIC X(9) VALUE SPACES.
02 FILLER PIC X(14) VALUE "STUDENT NUMBER".
02 FILLER PIC X(8) VALUE SPACES.
02 FILLER PIC X(12) VALUE "STUDENT NAME".
02 FILLER PIC X(15) VALUE SPACES.
02 FILLER PIC X(3) VALUE "AGE".
02 FILLER PIC X(8) VALUE SPACES.
02 FILLER PIC X(9) VALUE "ALLOWANCE".
01 PRINT-LINE.
02 FILLER PIC X(9) VALUE SPACES.
02 SNO-OUT PIC X(10).
02 FILLER PIC X(12) VALUE SPACES.
02 SNAME-OUT PIC X(25).
02 FILLER PIC X(2) VALUE SPACE.
02 AGE-OUT PIC Z9.
02 FILLER PIC X(9) VALUE SPACES.
02 ALL-OUT PIC ZZZ.99.
01 E-O-F PIC XXX VALUE "NO".
PROCEDURE DIVISION.
OPEN INPUT STUDENT-IN
OUTPUT STUDENT-OUT.
WRITE PRINT-REC FROM HDG-1 BEFORE 1 LINE.
WRITE PRINT-REC FROM HDG-2 AFTER 2 LINES.
MOVE SPACES TO PRINT-REC.
WRITE PRINT-REC AFTER 1 LINE.
PERFORM READ-RTN UNTIL E-O-F = "YES".
PERFORM CLOSE-RTN.
READ-RTN.
READ STUDENT-IN AT END MOVE "YES" TO E-O-F.
MOVE STUD-NO TO SNO-OUT.
MOVE STUD-NAME TO SNAME-OUT.
MOVE STUD-AGE TO AGE-OUT.
MOVE STUD-ALLOWANCE TO ALL-OUT.
WRITE PRINT-REC FROM PRINT-LINE AFTER 1 LINE.
CLOSE-RTN.
CLOSE STUDENT-IN, STUDENT-OUT.
STOP RUN.
What I want to achieve is just to output the file correctly but the error only inputs the HDG-1 and then the rest blank.
To answer your question: COBOL accept numeric data however you define it.
So for "text data" (as long as it isn't UTF-16 or another multibyte encoded file) PIC 99 (which says "two digits in the default USAGE DISPLAY - so one byte per digit) is perfectly fine.
As with every other language: "never trust input data" is something I can recommend. For example: someone could run this program with a file that was saved with an UTF-8 encoded character in the name and then it "looks" right but the code has an unexpected shift in its data. For COBOL things like FUNCTION TEST-NUMVAL(inp) [ignores spaces and allows decimal-point] or IS NUMERIC (strict class test) can be useful.
Using data-check you could for example also skip empty lines or leading/trailing extra data (temporary rulers, headline, summary, ...).
For the actual problem:
It looks like you feed the program with a "common" text file, but you actually did not specify this so your COBOL implementation uses the default SEQUENTIAL. Because of the missing check of the input data you did not spot this directly.
To align expectations and code:
SELECT STUDENT-IN ASSIGN TO "C:\STUD-IN.DAT"
ORGANIZATION IS LINE SEQUENTIAL.
SELECT STUDENT-OUT ASSIGN TO "C:\STUD-OUT.DAT"
ORGANIZATION IS LINE SEQUENTIAL.

Edit an alpha variable Cobol '12.3' to '12,30 '

How does Cobol to transform a variable of this format 1234,5 to 0000000001234,50.
01 VAR1 X(16) '1234,5'
01 VAR2 X(16)
01 VAROUT REDEFINES VAR2
03 VAROUT-INT X(13)
03 VAROUT-PNT X(01)
03 VAROUT-DEC X(02)
STRING VAR1 DELIMITED BY ',' INTO VAR-INT
I have used one of the general methods of editing a PICTURE clause - Simple Insertion editing - to achieve the expected result.
IDENTIFICATION DIVISION.
PROGRAM-ID. HELLO-WORLD.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-A PIC X(16) VALUE '1234,5'.
01 WS-B PIC 9999999999999,90.
PROCEDURE DIVISION.
MOVE WS-A TO WS-B.
DISPLAY WS-B.
STOP RUN.
Result:
0000000001234,50
This is the simplest way I know.
identification division.
program-id. dpic.
environment division.
configuration section.
special-names.
decimal-point is comma.
data division.
working-storage section.
1 var1 pic x(16) value "1234,5".
1 var2.
2 var2-num pic 9(13),99.
procedure division.
begin.
display var1
move function numval (var1) to var2-num
display var2
stop run
.
The result is:
1234,5
0000000001234,50

COBOL COMPUTE decimal values from a file

Trying to understand compute. Would it be correct to calculate the sum of the earned credits using FSemesterTotal which is a PIC 99V99 like this? COMPUTE FSemesterTotal = Earned + Earned. I think there is supposed to be a counter in my loop to check if i read in the first earned value so i can add it to the second value coming in not sure how to accomplish this in COBOL.
Currently my input is like this,
CMPS161 ALGORITHM DSGN/IMPLMNT I A 3.00
ENGL322 INTRO TO PROF/TECH WRITING A 3.00
MATH241 ELEM STATISTICS B 3.00
ART 106 SURV WORLD ART HIST II A 3.00
BIOL152 GENERAL BIOL LAB I B 1.00
CMPS257 DISCRETE STRUCTURE A 3.00
CMPS28O ALGORITHM DSGN/IMPLEM II B 3.00
CMPS290 COMPUTER ORGANIZATION A 3.00
CMPS390 DATA STRUCTURES B 3.00
GBIO153 GENERAL BIOL II B 3.00
CMPS294 INTERNET PROGRAMMING B 3.00
CMPS315 SYSTEM ADMINISTRATION A 3.00
CMPS329 COMPUTER NETWORKING SECURITY A 3.00
CMPS383 INFORMATION SYSTEMS A 3.00
CMPS415 INTERGRATED TECH SYSTEMS B 3.00
COBOL CODE
IDENTIFICATION DIVISION.
PROGRAM-ID. P2.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT myInFile ASSIGN TO "P2In.dat".
SELECT myOutFile ASSIGN TO "P2Out.dat".
DATA DIVISION.
FILE SECTION.
FD myInFile.
01 inRecord.
02 Course PIC X(13).
02 Title PIC X(32).
02 Grade PIC X(4).
02 Earned PIC 9V99.
02 FILLER PIC X(3).
FD myOutFile.
01 outRecord.
02 myCourse PIC X(13).
02 myTitle PIC X(32).
02 myGrade PIC X(4).
02 myEarned PIC 9.99.
02 FILLER PIC X(3).
WORKING-STORAGE SECTION.
01 E0F PIC X(3) VALUE "NO ".
01 NAME-HDR.
05 FILLER PIC X(10) VALUE "NAME HERE ".
01 SCHOOLID-HDR.
05 FILLER PIC X(8) VALUE "SCHOOLID"
01 COLUMN-HDR.
05 CCourse PIC X(6) VALUE "COURSE".
05 CSpace PIC X(7) VALUE SPACES.
05 HTitle PIC X(5) VALUE "TITLE".
05 HSpace PIC X(27) VALUE SPACES.
05 CGrade PIC XX VALUE "GR".
05 CSpace PIC XXX VALUE SPACES.
05 CEarned PIC X(6) VALUE "EARNED".
05 QSpace PIC X(4) VALUE SPACES.
05 Qpts PIC X(4) VALUE "Qpts".
01 FOOTER-SMS.
05 FSemester PIC X(28) VALUE " SEMESTER".
05 FSpaces PIC x(21) VALUE SPACES.
05 FSemesterTotal PIC 99V99.
01 FOOTER-CUMUL.
05 FCumulative PIC X(30) VALUE" CUMULATIVE".
05 FSpaces PIC X(19) VALUE SPACES.
05 FCumulTotal PIC 99V99.
01 QPTS-VAL.
05 QSpace PIC X(5) VALUE SPACES.
05 QPtsValue PIC 99V99.
01 GPA.
05 GSpace PIC XX VALUE SPACES.
05 GpaScore PIC 9.99.
PROCEDURE DIVISION.
MAIN-PROGRAM.
PERFORM HEADER.
PERFORM FILE-IO.
PERFORM CLOSING.
STOP RUN.
HEADER.
OPEN INPUT myInFile
OUTPUT myOutFile.
WRITE outRecord FROM NAME-HDR.
WRITE outRecord FROM SCHOOLID-HDR
AFTER ADVANCING 1 LINE.
WRITE outRecord FROM COLUMN-HDR
AFTER ADVANCING 2 LINES.
MOVE SPACES TO outRecord.
WRITE outRecord
AFTER ADVANCING 1 LINE.
FILE-IO.
READ myInFile
AT END
MOVE "YES" TO EOF.
DISPLAY NAME-HDR.
DISPLAY SCHOOLID-HDR.
DISPLAY SPACES.
DISPLAY SPACES.
DISPLAY "FALL 2014"
DISPLAY COLUMN-HDR.
PERFORM PROCESS-RECORD
UNTIL EOF = "YES".
PROCESS-RECORD.
MOVE Course to myCourse.
MOVE Title to myTitle.
MOVE Grade to myGrade.
MOVE Earned to myEarned.
WRITE outRecord
AFTER ADVANCING 1 LINE.
READ myInFile
AT END
MOVE "YES" TO EOF.
NOT AT END
IF myCourse = "ART 106 " THEN
DISPLAY FOOTER-SMS, QPTS-VAL, GPA
DISPLAY FOOTER-CUMUL, QPTS-VAL, GPA
DISPLAY SPACES.
DISPLAY "SPRING 2015"
END-IF.
IF myCourse = "CMPS285 " THEN
DISPLAY FOOTER-SMS, QPTS-VAL, GPA
DISPLAY FOOTER-CUMUL, QPTS-VAL, GPA
DISPLAY SPACES.
DISPLAY "FALL 2015"
END-IF.
IF myCourse = "CMPS294 " THEN
DISPLAY FOOTER-SMS, QPTS-VAL, GPA
DISPLAY FOOTER-CUMUL, QPTS-VAL, GPA
DISPLAY SPACES.
DISPLAY "SPRING 2016"
END-IF.
CLOSING.
DISPLAY FOOTER-SMS, QPTS-VAL, GPA.
DISPLAY FOOTER-CUMUL, QPTS-VAL, GPA.
CLOSE myInFile
myOutFile.
The question was: "Can I use COMPUTE this way?"
The answer is:
Yes, but you likely want to add a ON SIZE ERROR to cater for a possible size overflow, just in case your input data has too many entries.
If the question behind the question is: "Will the program work?"
The answer is no:
Despite the issues Brian already pointed out: you'll need a de-editing to change the data from 9.99 (4 bytes, not usable for arithmetic) to 9v99 (3 bytes, usable for arithmetic.
And if you don't use an ISAM file which is validated by the runtime: Always validate file input (the file may be broken and you likely don't want to abend or produce wrong results).

Read and jump first line and anothers lines in file

How I can read a .dat file with struct like that: ( A = ALPHANUMERIC && N = NUMERIC )
0AAAAAAAANNNN (233 BLANK SPACES ) 999999 ( SEQUENTIAL NUMBER ONE BY ONE )
1NNNNNNNNNNNNAAAAAAAAAAAAAAAAAAA (194 BLANK SPACES) 999999 (SEQUENTIAL NUMBER ONE BY ONE)
2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA (194 BLANK SPACES) 999999 (SEQUENTIAL NUMBER ONE BY ONE)
1NNNNNNNNNNNNAAAAAAAAAAAAAAAAAAA (194 BLANK SPACES) 999999 (SEQUENTIAL NUMBER ONE BY ONE)
2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA (194 BLANK SPACES) 999999 (SEQUENTIAL NUMBER ONE BY ONE)
1NNNNNNNNNNNNAAAAAAAAAAAAAAAAAAA (194 BLANK SPACES) 999999 (SEQUENTIAL NUMBER ONE BY ONE)
2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA (194 BLANK SPACES) 999999 (SEQUENTIAL NUMBER ONE BY ONE)
1NNNNNNNNNNNNAAAAAAAAAAAAAAAAAAA (194 BLANK SPACES) 999999 (SEQUENTIAL NUMBER ONE BY ONE)
2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA (194 BLANK SPACES) 999999 (SEQUENTIAL NUMBER ONE BY ONE)
9 (245 BLANK SPACES) 999999 (SEQUENTIAL NUMBER ONE BY ONE)
So, I know, how I can make a program to read this in C/C++ or in C#, but, I try to make in Cobol, just for study....
But, I don't know what the command I need to use to open the file with this style ( I just know the:
ORGANIZATION IS LINE SEQUENTIAL.
I think, exist a another command to open with custon instructions... i don't know...
So, btw, how I can open the file and read the informations ??
( i just need to read the line 1 on time, and, I need to read the line 2 and 3 always paried ... 4 and 5 && 6 and 7 && 8 and 9 ... )
and, I whant to show that information with DISPLAY ( just for study )
Thanks :)
Something like this below your FD:
01 INPUT-RECORD.
05 IR-RECORD-TYPE PIC X.
88 INPUT-RECORD-IS-HEADER VALUE '0'.
88 INPUT-RECORD-IS-DATA1 VALUE '1'.
88 INPUT-RECORD-IS-DATA2 VALUE '2'.
88 INPUT-RECORD-IS-TRAILER VALUE '9'.
05 FILLER PIC X(whatever).
You may need a "trailing" byte for a record-delimiter, I don't know, and you'll have to sort out the lengths, as they seem to vary.
These in Working-Storage:
01 INPUT-RECORD-HEADER.
05 IRH-RECORD-TYPE PIC X.
05 IRH-ITEM1 PIC X(8).
05 IRH-ITEM2 PIC 9(4).
05 FILLER PIC X(233).
05 IRH-SEQUENCE PIC X(6)
01 INPUT-RECORD-DATA1.
05 IRD1-RECORD-TYPE PIC X.
05 IRD1-ITEM1 PIC 9(14).
05 IRD1-ITEM1 PIC X(19).
05 FILLER PIC X(194).
05 IRD1-SEQUENCE PIC X(6)
01 INPUT-RECORD-DATA2.
05 IRD2-RECORD-TYPE PIC X.
05 IRD2-ITEM1 PIC X(33).
05 FILLER PIC X(194).
05 IRD2-SEQUENCE PIC X(6)
01 INPUT-RECORD-TRAILER.
05 IRT-RECORD-TYPE PIC X.
05 FILLER PIC X(245).
05 IRT-SEQUENCE PIC X(6).
You have to read each record, one at a time. Identify it. Put it in the correct W-S definition. When you read a "2" you can process the "1" you have stored along with the "2".
My datanames aren't very good, as I don't know what your data is. Also I have not "formatted" the definitions, which will make them more readable when you do it.
For OpenCOBOL, here is a sample standard in/standard out filter program:
>>SOURCE FORMAT IS FIXED
*> ***************************************************************
*><* ===========
*><* filter
*><* ===========
*><* :Author: Brian Tiffin
*><* :Date: 20090207
*><* :Purpose: Standard IO filters
*><* :Tectonics: cobc -x filter.cob
*> ***************************************************************
identification division.
program-id. filter.
environment division.
configuration section.
input-output section.
file-control.
select standard-input assign to keyboard.
select standard-output assign to display.
data division.
file section.
fd standard-input.
01 stdin-record pic x(32768).
fd standard-output.
01 stdout-record pic x(32768).
working-storage section.
01 file-status pic x value space.
88 end-of-file value high-value
when set to false is low-value.
*> ***************************************************************
procedure division.
main section.
00-main.
perform 01-open
perform 01-read
perform
until end-of-file
perform 01-transform
perform 01-write
perform 01-read
end-perform
.
00-leave.
perform 01-close
.
goback.
*> end main
support section.
01-open.
open input standard-input
open output standard-output
.
01-read.
read standard-input
at end set end-of-file to true
end-read
.
*> All changes here
01-transform.
move stdin-record to stdout-record
.
*>
01-write.
write stdout-record end-write
.
01-close.
close standard-input
close standard-output
.
end program filter.
*><*
*><* Last Update: dd-Mmm-yyyy
and here is a demonstration of using LINAGE that just happens to read in a text file.
*****************************************************************
* Example of LINAGE File Descriptor
* Author: Brian Tiffin
* Date: 10-July-2008
* Tectonics: $ cocb -x linage-demo.cob
* $ ./linage-demo <filename ["linage-demo.cob"]>
* $ cat -n mini-report
*****************************************************************
IDENTIFICATION DIVISION.
PROGRAM-ID. linage-demo.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
select optional data-file assign to file-name
organization is line sequential
file status is data-file-status.
select mini-report assign to "mini-report".
DATA DIVISION.
FILE SECTION.
FD data-file.
01 data-record.
88 endofdata value high-values.
02 data-line pic x(80).
FD mini-report
linage is 16 lines
with footing at 15
lines at top 2
lines at bottom 2.
01 report-line pic x(80).
WORKING-STORAGE SECTION.
01 command-arguments pic x(1024).
01 file-name pic x(160).
01 data-file-status pic 99.
01 lc pic 99.
01 report-line-blank.
02 filler pic x(18) value all "*".
02 filler pic x(05) value spaces.
02 filler pic x(34)
VALUE "THIS PAGE INTENTIONALLY LEFT BLANK".
02 filler pic x(05) value spaces.
02 filler pic x(18) value all "*".
01 report-line-data.
02 body-tag pic 9(6).
02 line-3 pic x(74).
01 report-line-header.
02 filler pic x(6) VALUE "PAGE: ".
02 page-no pic 9999.
02 filler pic x(24).
02 filler pic x(5) VALUE " LC: ".
02 header-tag pic 9(6).
02 filler pic x(23).
02 filler pic x(6) VALUE "DATE: ".
02 page-date pic x(6).
01 page-count pic 9999.
PROCEDURE DIVISION.
accept command-arguments from command-line end-accept.
string
command-arguments delimited by space
into file-name
end-string.
if file-name equal spaces
move "linage-demo.cob" to file-name
end-if.
open input data-file.
read data-file
at end
display
"File: " function trim(file-name) " open error"
end-display
go to early-exit
end-read.
open output mini-report.
write report-line
from report-line-blank
end-write.
move 1 to page-count.
accept page-date from date end-accept.
move page-count to page-no.
write report-line
from report-line-header
after advancing page
end-write.
perform readwrite-loop until endofdata.
display
"Normal termination, file name: "
function trim(file-name)
" ending status: "
data-file-status
end-display.
close mini-report.
* Goto considered harmful? Bah! :)
early-exit.
close data-file.
exit program.
stop run.
****************************************************************
readwrite-loop.
move data-record to report-line-data
move linage-counter to body-tag
write report-line from report-line-data
end-of-page
add 1 to page-count end-add
move page-count to page-no
move linage-counter to header-tag
write report-line from report-line-header
after advancing page
end-write
end-write
read data-file
at end set endofdata to true
end-read
.
*****************************************************************
* Commentary
* LINAGE is set at a 20 line logical page
* 16 body lines
* 2 top lines
* A footer line at 15 (inside the body count)
* 2 bottom lines
* Build with:
* $ cobc -x -Wall -Wtruncate linage-demo.cob
* Evaluate with:
* $ ./linage-demo
* This will read in linage-demo.cob and produce mini-report
* $ cat -n mini-report
*****************************************************************
END PROGRAM linage-demo.
With those samples, along with Gilbert's answer, you should have enough to tackle your problem, with the caveat that these examples are shy on proper error handling, so be careful is this is homework or a paid assignment. For an example of standard input/output or by filename depending on command line arguments (or lack thereof), see the ocdoc.cob program in the OpenCOBOL FAQ.
Offtopic: Output of an ocdoc pass over ocdoc.cob itself can be seen at http://opencobol.add1tocobol.com/ocdoc.html (Why mention it? The COBOL lexicon highlighter for Pygments has just been accepted into main. Any Pygments pulled after version 1.6 will allow for COBOL (context free) lexical highlighting.)
You write an ordinary Cobol program that reads a file.
The first byte (character) of the record is either 0, 1, 2, or 9.
Define a Working-Storage area (01 level) for each of the 4 record types. Then, after you read the record, you move it from the input area to the appropriate Working-Storage area for the record.
Then you process the record how you wish from one of the 4 Working-Storage areas.

Resources