Search code examples
cobol

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.


Solution

  • 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.