What am I missing?
QualityPoints PIC 9v99 VALUE 4.00.
XValue PIC 9v99 VALUE 3.00.
Total PIC 999v99.
outTotal PIC zz9V99.
COMPUTE Total = QualityPoints * XValue.
MOVE Total to outTotal.
When I perform this compute my outTotal is 11.2 what happened?
Please see the reproducable results using online compiler which has all my code and files available.
There is absolutely nothing wrong with your code other than the fact that it's not a complete program that you posted (no divisions or sections, no levels on your data, possibly other things that I couldn't be bothered testing)
Well, that and the fact that the link to the online compiler site has long since gone, proof once again that SO question should be completely self-contained with all information needed. When posting questions and answers, I always ask myself if they'll still be useful if the rest of the internet totally disappears.
However, using that same site, the following program(a) does work as expected:
IDENTIFICATION DIVISION.
PROGRAM-ID. PAX-DIABLO.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 QualityPoints PIC 9v99 VALUE 4.00.
01 XValue PIC 9v99 VALUE 3.00.
01 Total PIC 999v99.
01 outTotal PIC zz9.99.
PROCEDURE DIVISION.
COMPUTE Total = QualityPoints * XValue.
MOVE Total to outTotal.
DISPLAY outTotal.
STOP RUN.
It produces the expected answer, as per the below transcript:
$cobc -x -free *.cobc -o main
$main
12.00
(a) See, this answer is self-contained, see how easy that was :-)
Related
problem
I'm a beginner in COBOL and I'm running into this annoying problem which I can not find a solution for.
I want to add the value of the amount of sales to another numeric variable so that I can use it as a condition for a perform loop but when it tries to add that value to this new variable it triggers this error:
"libcob: PROG-PAGOS-F.cbl: 57: 'WS-CANTIDAD-VENTAS' not numeric: '2 '
WARNING - Implicit CLOSE of REG-VENDEDORES ('REG-MAESTRO.DAT')"
and I can not find a way around it; I'm stuck.
current code (not finished)
What this program is supposed to do is output data of employees' salary, sells, price of each sell into a file and then do some other operations with them but I can't do any progress because of this error, I'd love some help, and perhaps some advices to makes this code better. Thank you!
My variables are in Spanish because I'm Argentinian, sorry if it's hard to understand.
IDENTIFICATION DIVISION.
PROGRAM-ID. PROG-PAGOS-F.
AUTHOR. LUCAS GALEANO.
DATE-WRITTEN. 1/2/2023.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT REG-VENDEDORES ASSIGN TO "REG-MAESTRO.DAT"
ORGANIZATION IS LINE SEQUENTIAL.
SELECT REG-VENTAS ASSIGN TO "REG-VENTAS-MAESTRO.DAT"
ORGANIZATION IS LINE SEQUENTIAL.
DATA DIVISION.
FILE SECTION.
FD REG-VENDEDORES.
01 VENDEDORES PIC 9(11).
FD REG-VENTAS.
01 COBRO-VENTAS PIC 9(5).
WORKING-STORAGE SECTION.
01 WS-VENDEDORES.
05 WS-EMPLEADO PIC 999.
05 WS-SUELDO-BASE PIC 9(5).
05 WS-CANTIDAD-VENTAS PIC 999.
77 WS-COBROS PIC 9(5).
77 WS-SUM-VENTAS PIC 99.
77 WS-CONTADOR PIC 99 VALUE ZEROS.
01 WS-TABLAS.
05 WS-REGISTRO-COBROS PIC 9(5)
OCCURS 100 TIMES.
PROCEDURE DIVISION.
BEGIN-OUTPUT.
OPEN OUTPUT REG-VENDEDORES.
DISPLAY "INGRESE DATOS SOLICITADOS".
PERFORM INGRESO-DATOS-EMPLEADOS.
PERFORM UNTIL WS-VENDEDORES EQUALS SPACES
WRITE VENDEDORES FROM WS-VENDEDORES
PERFORM INGRESO-DATOS-EMPLEADOS
END-PERFORM.
DISPLAY "INGRESE COBROS DE CADA VENTA:".
PERFORM INGRESO-VENTAS WITH TEST AFTER
UNTIL WS-CONTADOR EQUALS WS-SUM-VENTAS
MOVE WS-COBROS TO WS-REGISTRO-COBROS(1)
CLOSE REG-VENDEDORES.
STOP RUN.
INGRESO-DATOS-EMPLEADOS.
DISPLAY "EEE$$$$$VVV".
ACCEPT WS-VENDEDORES.
ADD WS-CANTIDAD-VENTAS TO WS-SUM-VENTAS.
INGRESO-VENTAS.
ADD 1 TO WS-CONTADOR.
DISPLAY "$$$$$".
ACCEPT WS-COBROS.
example input data
INGRESE DATOS SOLICITADOS
EEE$$$$$VVV
1 400002
There is no implicit conversion in ACCEPT data-item, so you need to convert - and validate it on your own (or switch to "extended" screenio with ACCEPT data-item AT / SCREEN SECTION, but then the result would be depending on the actual COBOL environment).
The easiest option to convert (will sip leading/trailing spaces and invalid data) is something like the following:
ACCEPT WS-VENDEDORES. *> all data may now be invalid
MOVE FUNCTION NUMVAL (WS-EMPLEADO) TO WS-EMPLEADO
MOVE FUNCTION NUMVAL (WS-SUELDO-BASE) TO WS-SUELDO-BASE
MOVE FUNCTION NUMVAL (WS-CANTIDAD-VENTAS) TO WS-CANTIDAD-VENTAS
*> all data is now valid
For validation you may want to use FUNCITON TEST-NUMVAL (data-to-verify).
In any case I'd suggest to check out SCREEN SECTION, as this would allow you to input the data in three separate fields and commonly would do validation and conversion "on the fly".
I am trying to use the SORT feature of COBOL.
IDENTIFICATION DIVISION.
PROGRAM-ID. ******.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT IN-FILE ASSIGN TO IFILE.
SELECT OUT-FILE ASSIGN TO OFILE.
SELECT SORT-FILE ASSIGN TO SORTWK.
DATA DIVISION.
FILE SECTION.
SD SORT-FILE.
01 SORT-REC.
05 S-NAME PIC X(20).
05 S-ADDRESS PIC X(20).
05 S-ID PIC 9(9).
05 S-CREDITS PIC 99.
05 FILLER PIC X(29).
FD IN-FILE.
01 IN-REC.
05 IN-NAME PIC X(20).
05 IN-ADDRESS PIC X(20).
05 IN-ID PIC 9(9).
05 IN-CREDITS PIC 99.
05 FILLER PIC X(29).
FD OUT-FILE.
01 OUT-REC PIC X(80).
WORKING-STORAGE SECTION.
01 WS-WORK-AREA.
05 EOF-SW PIC X VALUE SPACES.
01 WS-DETAIL-LINES.
05 RPT-LINE.
10 OUT-NAME PIC X(20).
10 OUT-ADDRESS PIC X(20).
10 OUT-ID PIC 9(9).
10 OUT-CREDITS PIC 99.
10 FILLER PIC X(29) VALUE SPACES.
PROCEDURE DIVISION.
MAIN-RTN.
SORT SORT-FILE
ON ASCENDING KEY S-ID
INPUT PROCEDURE READ-RELEASE
OUTPUT PROCEDURE RETURN-WRITE.
STOP RUN.
OPEN-FILES-RTN.
OPEN INPUT IN-FILE.
OPEN OUTPUT OUT-FILE.
OPEN-FILES-RTN-EXIT. EXIT.
READ-RELEASE.
PERFORM OPEN-FILES-RTN.
PERFORM READ-INPUT
UNTIL EOF-SW = 'F'.
READ-RELEASE-RTN-EXIT. EXIT.
READ-INPUT.
READ IN-FILE
AT END MOVE 'F' TO EOF-SW.
RELEASE SORT-REC FROM IN-REC.
RETURN-WRITE.
MOVE SPACES TO EOF-SW.
PERFORM WRITE-FL
UNTIL EOF-SW = 'F'.
PERFORM CLOSE-FILES-RTN.
RETURN-WRITE-RTN-EXIT. EXIT.
WRITE-FL.
RETURN SORT-FILE RECORD INTO OUT-REC
AT END MOVE 'F' TO EOF-SW.
WRITE OUT-REC.
WRITE-FL-RTN-EXIT. EXIT.
CLOSE-FILES-RTN.
CLOSE IN-FILE OUT-FILE.
CLOSE-FILES-RTN-EXIT. EXIT.
I am able to compile this program but when it comes to execute, it gives the following error:
CEE3204S The system detected a protection exception (System Completion
Code=0C4). From compile unit SU98PGM6 at entry point SU98PGM6
at compile unit offset +0005517A at address 1F45517A.
I have searched about this error but I couldn't figure out what is causing this problem in my program.
I have made some changes after taking note of the comments, but am still getting the same problem with this changed code.
READ-RELEASE.
PERFORM OPEN-FILES-RTN.
PERFORM READ-INPUT
UNTIL EOF-SW = 'F'.
READ-RELEASE-RTN-EXIT. EXIT.
READ-INPUT.
READ IN-FILE
AT END MOVE 'F' TO EOF-SW
NOT AT END PERFORM PROCESS-INPUT.
PROCESS-INPUT.
MOVE IN-NAME TO S-NAME.
MOVE IN-ADDRESS TO S-ADDRESS.
MOVE IN-ID TO S-ID.
MOVE IN-CREDITS TO S-CREDITS.
RELEASE SORT-REC.
PROCESS-INPUT-RTN-EXIT. EXIT.
RETURN-WRITE.
MOVE SPACES TO EOF-SW.
PERFORM WRITE-FL
UNTIL EOF-SW = 'F'.
PERFORM CLOSE-FILES-RTN.
RETURN-WRITE-RTN-EXIT. EXIT.
WRITE-FL.
RETURN SORT-FILE RECORD INTO OUT-REC
AT END MOVE 'F' TO EOF-SW
NOT AT END PERFORM PROCESS-OUTPUT.
WRITE-FL-RTN-EXIT. EXIT.
PROCESS-OUTPUT.
MOVE S-NAME TO OUT-NAME.
MOVE S-ADDRESS TO OUT-ADDRESS.
MOVE S-ID TO OUT-ID.
MOVE S-CREDITS TO OUT-CREDITS.
WRITE OUT-REC.
PROCESS-OUTPUT-RTN-EXIT. EXIT.
Here is my JCL
//******** JOB 1,'*****',NOTIFY=*******
//JOBLIB DD DSN=*******.*******.*******,DISP=SHR
//STEP0 EXEC PGM=SU98PGM6
//IFILE DD DSN=*******.*******.*******.*******(*******),DISP=SHR
//SORTWK DD DSN=*******.*******.*******.*******,DISP=SHR
//OFILE DD DSN=*******.*******.*******.*******,
// DISP=(NEW,CATLG,DELETE),
// DCB=(BLKSIZE=0,LRECL=80,RECFM=FB),
// SPACE=(CYL,(1,1),RLSE),
// UNIT=SYSDA
/*
The output for the //SYSOUT DD can be confusing when using COBOL, SORT (DFSORT or SyncSORT) and Language Environment which may give you run-time messages, as they all use SYSOUT by default, and the messages will appear intermingled.
Fortunately, you can change the default behaviour, as shown here for DFSORT and Language Envrionment (there are many ways in LE to specify the option, the most flexible is a //CEEOPTS DD in your JCL): https://stackoverflow.com/a/29521423/1927206
COBOL itself has a compiler option, OUTDD. the value defaults to SYSOUT, but you can specify any OUTDD(xxxx)
OK, having seen your JCL and your comments about how a DISPLAY statement in your program affects the data, I've managed a partial reproduce.
I use DFSORT, and I don't get your exact behaviour so I'm going to assume you use SYNCSORT.
The behaviour I can get having removed the //SYSOUT DD from my JCL is this message:
IGZ0026W The SORT-RETURN special register was never referenced, but
the current content indicated the sort or merge operation in program
STOB87 on line number 46 was unsuccessful.
When I add the //SYSOUT back into the JCL, the program runs successfully.
When I take the //SYSOUT out and add a DISPLAY before the SORT, the program works. This is because if there is no //SYSOUT in the JCL the first DISPLAY which is executed will cause one to be dynamically created (the output will appear in the spool as though it were a separate JOB, with the same name and jobnumber).
In my case DFSORT is complaining about the missing //SYSOUT. With the DISPLAY, the //SYSOUT is not missing at the time DFSORT starts.
I have to assume that SYNCSORT is facing a similar issue, but the run-time COBOL message is not produced and SYNCSORT itself fails on the next RELEASE.
Although this seems like a simple and common issue, because we always copy a piece of JCL to make a new piece of JCL, //SYSOUT is always there.
Consult the Enterprise COBOL Programming Guide, Chapter 12 I think, and see how to use SORT-RETURN to confirm that the SORT completed successfully.
I'm pretty sure that if you include the //SYSOUT in your JCL you will no longer get the abend, whether or not you have a DISPLAY.
The reason for the high "offset" is that the abend processor is unable to identify the entry-point of your SORT product, so keeps searching backwards to find something it can identify, and locates your program entry-point and then calculates the incorrect offset. This can also happen when CALLing some Assembler programs.
Firstly, to your S0C4, which is a Protection Exception, which means you are attempting to access storage which doesn't "belong" to you for the access you want.
You are getting a S0C4 in program SU98PGM6. You have cunningly obliterated your PROGRAM-ID name when posting here, which probably hasn't helped.
SU98PGM6 is not your program. The abend (Abnormal End) is at offset X'0005517A' in the failing program. That means, from the "start" of the program (the Entry Point) the instruction at offset/displacement X'0005517A' is the one which attempted the bad thing. That offset, which in decimal is 348538, indicates a fairly large program. Your program is very small.
There are many ways that this can come about. For instance, you may have copied the JCL from somewhere else, and failed to change the EXEC PGM=. You may have a program of the same name as yours earlier in the STEPLIB concatenation. You may have compiled the wrong program. Etc.
When you get an abend, always confirm that the compile listing you have is for the program that abended. An easy and useful way to do this is:
01 W-WHEN-COMPILED PIC X(8)BX(8).
...
* where it can only be executed once:
MOVE WHEN-COMPILED TO W-WHEN-COMPILED
DISPLAY
"yourname COMPILED ON "
W-WHEN-COMPILED
"yourname" you replace with the text following PROGRAM-ID.
The output will be like this:
yourname COMPILED ON 11/24/15 10.35.26
That will match the date/time in the heading on each page of the compile listing.
If you run a program and don't get that output, or you get output but it is not the output expected, then you know your program is not the one running.
Now to your program.
You do not need to use input/output procedures to be able to SORT
You should always use the FILE STATUS clause of the SELECT statement, and always check the file-status fields (one per file) that you define, after each IO operation. Testing the file-status field for an input file will allow you to identify end-of-file without the need for the tortuous AT END/NOT AT END construct
If you use sort procedures, COBOL does the IO. If you don't, and use compiler option FASTSRT, your SORT product will do the IO, which will be much more efficient than COBOL.
Unless you are selecting or reformatting records, you don't need the sort procedures
Since you are using INTO, which does an implicit MOVE of the record, you don't need to also MOVE the data individually
COBOL, since compilers supporting the 1985 Standard, which I'm fairly sure you will have, have "scope terminators". Prior to that, the only scope-terminator was the full-stop/period. These days, use the explicit, specific scope-terminators when using "imperative statements" and for all conditional statements. In your case, replace use READ/END-READ, RETURN/END-RETURN
Only use full-stops/periods in the PROCEDURE DIVISION where they are required, and not on a line of code. This aids the moving/copying of code from one location to another
Use 88-level condition-names for tests, rather than literals. You can make the name exactly meaningful, so nobody ever has to wonder what 'F' means in a particular context
To simply SORT a file in a COBOL program, look at SORT ... USING ... GIVING... and use compiler option FASTSRT (if possible).
You are not yet aware of the implications of paragraphs (or SECTIONs) and the EXIT statement.
When using PERFORM or a SORT PROCEDURE execution is transferred to the code in the paragraph, and returns control when the next paragraph is reached.
Your "exit" paragraphs as you have coded are never used, but someone looking at the code will assume (if they are silly, and a lot of people will make the assumption) that you have used THRU and they'll stick in a GO TO the "exit" paragraph. Then they'll be surprised that the program behaves badly (if they're luck) and will eventually work out that they have used GO TO to transfer control out of the range of the PERFORM/PROCEDURE.
If your local standards enforce the use of exit-paragraphs, then you must use THRU in your PERFORM and PROCEDURE statements.
Exit-paragraphs are entirely useless, and do nothing but provide a target-label for a GO TO, meaning that someone in the future will likely use a GO TO for "convenience".
Here's your original program with the exit-paragraphs removed:
IDENTIFICATION DIVISION.
PROGRAM-ID. ******.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT IN-FILE ASSIGN TO IFILE.
SELECT OUT-FILE ASSIGN TO OFILE.
SELECT SORT-FILE ASSIGN TO SORTWK.
DATA DIVISION.
FILE SECTION.
SD SORT-FILE.
01 SORT-REC.
05 S-NAME PIC X(20).
05 S-ADDRESS PIC X(20).
05 S-ID PIC 9(9).
05 S-CREDITS PIC 99.
05 FILLER PIC X(29).
FD IN-FILE.
01 IN-REC.
05 IN-NAME PIC X(20).
05 IN-ADDRESS PIC X(20).
05 IN-ID PIC 9(9).
05 IN-CREDITS PIC 99.
05 FILLER PIC X(29).
FD OUT-FILE.
01 OUT-REC PIC X(80).
WORKING-STORAGE SECTION.
01 WS-WORK-AREA.
05 EOF-SW PIC X VALUE SPACES.
01 WS-DETAIL-LINES.
05 RPT-LINE.
10 OUT-NAME PIC X(20).
10 OUT-ADDRESS PIC X(20).
10 OUT-ID PIC 9(9).
10 OUT-CREDITS PIC 99.
10 FILLER PIC X(29) VALUE SPACES.
PROCEDURE DIVISION.
SORT SORT-FILE
ON ASCENDING KEY S-ID
INPUT PROCEDURE READ-RELEASE
OUTPUT PROCEDURE RETURN-WRITE
GOBACK
.
OPEN-FILES-RTN.
OPEN INPUT IN-FILE
OPEN OUTPUT OUT-FILE
.
READ-RELEASE.
PERFORM OPEN-FILES-RTN
PERFORM READ-INPUT
UNTIL EOF-SW = 'F'
.
READ-INPUT.
READ IN-FILE
AT END MOVE 'F' TO EOF-SW
END-READ
RELEASE SORT-REC FROM IN-REC
.
RETURN-WRITE.
MOVE SPACES TO EOF-SW
PERFORM WRITE-FL
UNTIL EOF-SW = 'F'
PERFORM CLOSE-FILES-RTN
.
WRITE-FL.
RETURN SORT-FILE RECORD INTO OUT-REC
AT END MOVE 'F' TO EOF-SW
END-RETURN
WRITE OUT-REC
.
CLOSE-FILES-RTN.
CLOSE IN-FILE OUT-FILE
.
I've also changed the STOP RUN to GOBACK, which is much more flexible, and removed your first paragraph-name, as it is unnecessary and for people new to COBOL implies too much (COBOL itself has no concept of "main" as it may be pertinent in other languages you may know).
IDENTIFICATION DIVISION.
PROGRAM-ID. PROGRAM1.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT EMP-GRADE ASSIGN TO 'input.txt'
ORGANIZATION IS SEQUENTIAL
ACCESS MODE IS SEQUENTIAL
FILE STATUS IS WS-STATUS.
DATA DIVISION.
FILE SECTION.
FD EMP-GRADE.
01 NEWFILE.
05 FS-EMPID PIC 9(5).
05 FS-NAME PIC A(5).
05 FS-STREAM PIC X(5).
05 FS-GRADE PIC A(1).
05 FILLER PIC X(64).
WORKING-STORAGE SECTION.
01 WS-EOF PIC A(1) VALUE "N".
01 WS-STATUS PIC X(2).
PROCEDURE DIVISION.
MAIN-PARA.
OPEN INPUT EMP-GRADE.
PERFORM PARA1 THRU PARA1-EXIT UNTIL WS-EOF="Y".
CLOSE EMP-GRADE.
STOP RUN.
MAIN-PARA-EXIT.
EXIT.
PARA1.
READ EMP-GRADE
AT END MOVE "Y" TO WS-EOF
NOT AT END
IF FS-GRADE='A'
DISPLAY FS-EMPID , FS-NAME , FS-STREAM , FS-GRADE
END-IF
END-READ.
PARA1-EXIT.
EXIT.
input provided:
1234 sita comp A
2345 tina main B
5689 riya math A
but the output is coming :
1234 sita comp A
It is reading only the first record.
As Brian Tiffin is hinting at in the comments, it is your data which is the problem.
This:
05 FILLER PIC X(64).
Means that your records should be 64 bytes longer than they are.
If you have a fixed-length record, or only fixed-length records, under an FD, then the data all have to be the same length, and equal to what you have defined in your program.
It means, and behaviour depends on compiler, you only have one record as far as the COBOL program is concerned.
A good way to spot such things is to always count your input records, and count your output records, and records which should not be selected for output. You can then easily tell if anything has fallen between a crack.
Leaving that aside, here's your program with some adjustments:
IDENTIFICATION DIVISION.
PROGRAM-ID. PROGRAM1.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT EMP-GRADE ASSIGN TO 'input.txt'
ORGANIZATION IS SEQUENTIAL
ACCESS MODE IS SEQUENTIAL
FILE STATUS IS WS-STUDENT-GRADE-STATUS.
DATA DIVISION.
FILE SECTION.
FD EMP-GRADE.
01 NEWFILE.
05 FS-EMPID PIC 9(5).
05 FS-NAME PIC X(5).
05 FS-STREAM PIC X(5).
05 FS-GRADE PIC X(1).
05 FILLER PIC X(64).
WORKING-STORAGE SECTION.
01 WS-STUDENT-GRADE-STATUS PIC X(2).
88 END-OF-STUDENT-GRADE-FILE VALUE "10".
88 ERROR-ON-STUDENT-GRADE-FILE VALUE ZERO.
PROCEDURE DIVISION.
OPEN INPUT EMP-GRADE
* perform a paragraph to check FILE STATUS field is zero, using an 88.
PERFORM PRIMING-READ
PERFORM PROCESS-STUDENT-GRADE-FILE
UNTIL END-OF-STUDENT-GRADE-FILE
CLOSE EMP-GRADE
* perform a paragraph to check FILE STATUS field is zero, using an 88.
GOBACK
.
PRIMING-READ.
PERFORM READ-STUDENT-GRADE
.
READ-STUDENT-GRADE.
READ EMP-GRADE
* perform a paragraph to check FILE STATUS field is zero, using an 88.
.
PROCESS-STUDENT-GRADE-FILE.
IF FS-GRADE='A'
* To see the problem with your data, DISPLAY the 01-level
DISPLAY NEWFILE
DISPLAY FS-EMPID
FS-NAME
FS-STREAM FS-GRADE
END-IF
PERFORM READ-STUDENT-GRADE
.
If you use the FILE STATUS field, you should check it. Since you use it, you can use it to check for end-of-file without the AT END. If you use a "priming read" you don't need the AT END/NOT AT END tangle. If you code the minimum of full-stops/periods in the PROCEDURE DIVISION, you won't have a problem with them. Commas are never needed, so don't use them. Format your program for human readability. Use good descriptive names for everything. The THRU on a PERFORM invites the use of GO TO. As a learning, avoid the invitation.
If your class itself enforces particular ways to code COBOL, you'll have to use those ways. If so, I'd suggest you do both. The first couple of times at least, submit both to your tutor. Even if they tell you not to do that, continue doing dual examples when given tasks (just don't submit them any more). There is no reason for you to start off with bad habits.
Keep everything simple. If your code looks bad, make it look good through simplification and formatting.
Remember also that COBOL is all about fixed-length stuff. Get's us back to your original problem.
IDENTIFICATION DIVISION.
PROGRAM-ID. TEMP1 .
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-A PIC 9(2).
01 WS-B PIC 9(2).
PROCEDURE DIVISION.
ACCEPT WS-A.
COMPUTE WS-B ROUNDED = ( ( 9 / 5 ) * WS-A ) + 32.
DISPLAY WS-B.
STOP RUN.
This is my program for accepting temperature in Celcius and converting it to Fahrenheit. I have created a LOADLIB and a COPYLIB. Also one JCL for compilation and RUNJCL. No error is coming, but when I give any input (e.g. 98) in RUNJCL, it always shows 32 as output. What is the problem?
If the result you are getting is always 32, then WS-A is zero, because something multiplied by zero and adding 32 will always be 32.
I suspect that you have in your JCL something like this:
//SYSIN DD *
00212
When you do the ACCEPT, you will only get 00 from that.
When using ACCEPT for little testing programs it is a good idea to DISPLAY what you get, so you can see.
Either make WS-A larger, or the value on the card following your SYSIN smaller.
It if also possible you have other problems causing the value of WS-A to be treated as zero. So, can you paste the JCL from file 2 on the spool for your JOB. With the line-numbers it generated :-)
And the SYSIN card data (your 98). Look out particularly for any "SYSIN generated" statements in your JCL output.
Here's your program. I've got rid of unnecessary things, and changed the names of WS-A and WS-B. Now that WS-B has a proper name, you can see as you create it that it is the wrong length, it needs to be at least three digits.
ID DIVISION.
PROGRAM-ID. TEMP1.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 INPUT-CENTIGRADE PIC 9(2).
01 OUTPUT-FARENHEIT PIC 9(3).
PROCEDURE DIVISION.
ACCEPT INPUT-CENTIGRADE
DISPLAY
"CELSIUS COMING IN "
">"
INPUT-CENTIGRADE
"<"
COMPUTE OUTPUT-FARENHEIT ROUNDED
= ( ( 9 / 5 )
* INPUT-CENTIGRADE )
+ 32
DISPLAY
"FARENHEIT GOING OUT "
">"
OUTPUT-FARENHEIT
"<"
GOBACK
.
The output from running the program is:
CELSIUS COMING IN >98<
FARENHEIT GOING OUT >208<
Running this version of your program with "0098" for input gives this:
CELSIUS COMING IN >00<
FARENHEIT GOING OUT >032<
This is my code where iIam declaring a variable using OCCURS.
IDENTIFICATION DIVISION.
PROGRAM-ID. ARRAYEX.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT StudentFile ASSIGN TO "STUDENTS.DAT"
ORGANIZATION IS LINE SEQUENTIAL.
DATA DIVISION.
WORKING-STORAGE SECTION.
77 WS-FIRSTARR OCCURS 10 TIMES PIC 9(5).
PROCEDURE DIVISION.
DISPLAY "HELLO WORLD".
STOP RUN.
Error:
arrayex.cbl:12: Error: Level 77 item 'WS-FIRSTARR' cannot have OCCURS clause
Any reasons the compilation fails?
A 77 cannot have OCCURS. An 01 cannot have OCCURS. Levels 02-49 can have OCCURS.
Forget level 66 (used for the RENAMES clause) as your should not use it and are unlikely to ever see it.
An 88-level, a Condition Name, cannot have an occurs, but if the field which it is defined on is part of an OCCURS or subordinate to an OCCURS, the 88 will need subscripting like any 02- - 49-level which is also part of, or subordinate to, an OCCURS.
01 a-simple-array-structure.
05 the-data occurs 5 times pic 9(5).
Or you can get more complex.
01 b-structure.
95 the-key pic x(8).
05 some-data pic x(10).
05 some-more-data pic 9(7).
05 a-simple-array.
10 a-simple-array-item occurs 5 times
pic 9(5).
05 a-more-complex-array.
10 complex-entry occurs 10 times.
15 some-complex-data pic xx.
15 another-bit-of-complex-data
pic 9(5).
OCCURS can also be used to define multi-dimensional tables.
05 first-occurs occurs 5 times.
10 second-occurs occurs 5 times.
15 an-item pic xx.
This is still far from the full gamut of OCCURS, so start simple, practice, get it working, become more complex.
There is also OCCURS DEPENDING ON, a variable-length table. One thing at a time. Get a simple OCCURS working, not just the definition, but the use as well, with a field for a subscript, an index for a subscript and a literal for a subscript.
Then get more complex.
COBOL has several "magic" level numbers...
Level-66 items indicate a RENAMES clause is to be expected
Level-77 items are atomic, cannot be subdivided, cannot have an OCCURS clause.
Level-88 indicates a condition-name entry
See pages 5-4 and 5-5 of the programmer's guide.