RosettaCodeData/Task/Text-processing-2/COBOL/text-processing-2.cobol

164 lines
5.0 KiB
COBOL

IDENTIFICATION DIVISION.
PROGRAM-ID. text-processing-2.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT readings ASSIGN Input-File-Path
ORGANIZATION LINE SEQUENTIAL
FILE STATUS file-status.
DATA DIVISION.
FILE SECTION.
FD readings.
01 reading-record.
03 date-stamp PIC X(10).
03 FILLER PIC X.
03 input-data PIC X(300).
LOCAL-STORAGE SECTION.
78 Input-File-Path VALUE "readings.txt".
78 Num-Data-Points VALUE 48.
01 file-status PIC XX.
01 current-line PIC 9(5).
01 num-date-stamps-read PIC 9(5).
01 read-date-stamps-area.
03 read-date-stamps PIC X(10) OCCURS 1 TO 10000 TIMES
DEPENDING ON num-date-stamps-read
INDEXED BY date-stamp-idx.
01 offset PIC 999.
01 data-len PIC 999.
01 data-flag PIC X.
88 data-not-found VALUE "N".
01 data-field PIC X(25).
01 i PIC 99.
01 num-good-readings PIC 9(5).
01 reading-flag PIC X.
88 bad-reading VALUE "B".
01 delim PIC X.
PROCEDURE DIVISION.
DECLARATIVES.
readings-error SECTION.
USE AFTER ERROR ON readings
DISPLAY "An error occurred while using " Input-File-Path
DISPLAY "Error code " file-status
DISPLAY "The program will terminate."
CLOSE readings
GOBACK
.
END DECLARATIVES.
main-line.
OPEN INPUT readings
*> Process each line of the file.
PERFORM FOREVER
READ readings
AT END
EXIT PERFORM
END-READ
ADD 1 TO current-line
IF reading-record = SPACES
DISPLAY "Line " current-line " is blank."
EXIT PERFORM CYCLE
END-IF
PERFORM check-duplicate-date-stamp
*> Check there are 24 data pairs and see if all the
*> readings are ok.
INITIALIZE offset, reading-flag, data-flag
PERFORM VARYING i FROM 1 BY 1 UNTIL Num-Data-Points < i
PERFORM get-next-field
IF data-not-found
DISPLAY "Line " current-line " has missing "
"fields."
SET bad-reading TO TRUE
EXIT PERFORM
END-IF
*> Every other data field is the instrument flag.
IF FUNCTION MOD(i, 2) = 0 AND NOT bad-reading
IF FUNCTION NUMVAL(data-field) <= 0
SET bad-reading TO TRUE
END-IF
END-IF
ADD data-len TO offset
END-PERFORM
IF NOT bad-reading
ADD 1 TO num-good-readings
END-IF
END-PERFORM
CLOSE readings
*> Display results.
DISPLAY SPACE
DISPLAY current-line " lines read."
DISPLAY num-good-readings " have good readings for all "
"instruments."
GOBACK
.
check-duplicate-date-stamp.
SEARCH read-date-stamps
AT END
ADD 1 TO num-date-stamps-read
MOVE date-stamp
TO read-date-stamps (num-date-stamps-read)
WHEN read-date-stamps (date-stamp-idx) = date-stamp
DISPLAY "Date " date-stamp " is duplicated at "
"line " current-line "."
END-SEARCH
.
get-next-field.
INSPECT input-data (offset:) TALLYING offset
FOR LEADING X"09"
*> The fields are normally delimited by a tab.
MOVE X"09" TO delim
PERFORM find-num-chars-before-delim
*> If the delimiter was not found...
IF FUNCTION SUM(data-len, offset) > 300
*> The data may be delimited by a space if it is at the
*> end of the line.
MOVE SPACE TO delim
PERFORM find-num-chars-before-delim
IF FUNCTION SUM(data-len, offset) > 300
SET data-not-found TO TRUE
EXIT PARAGRAPH
END-IF
END-IF
IF data-len = 0
SET data-not-found TO TRUE
EXIT PARAGRAPH
END-IF
MOVE input-data (offset:data-len) TO data-field
.
find-num-chars-before-delim.
INITIALIZE data-len
INSPECT input-data (offset:) TALLYING data-len
FOR CHARACTERS BEFORE delim
.