I need help writing a small program in COBOL.
I wrote this piece of code:
IDENTIFICATION DIVISION.
PROGRAM-ID. CallC.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 INITBUF PIC X(10).
01 SHOWBUF PIC X(10).
01 BUF USAGE IS POINTER.
01 NUM PIC 9(10).
PROCEDURE DIVISION.
MOVE 10 to NUM.
CALL "getBuffer" USING BY VALUE NUM RETURNING BUF.
CALL "initBuffer" USING BY VALUE BUF RETURNING INITBUF.
CALL "showBuffer" USING BY VALUE BUF RETURNING SHOWBUF.
DISPLAY SHOWBUF.
STOP RUN.
How do I go about writing the DISPLAY result to a file?
Bill. Declare the file as in the example below. Move whatever you want to output into the output variable then Write outputVar
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT PARM-OUT ASSIGN TO PARMOUT.
*************************************************
DATA DIVISION.
FILE SECTION.
FD PARM-OUT
RECORDING MODE F.
01 PARMIN-REC.
05 PSID-IN PIC 9(09).
05 PCID-IN PIC 9(08).
05 IN-PCIDSEQ PIC 9(03).
Related
I just want to know why i can't see my records on my Notepad files, is there something wrong in my code? I created my Notepad files into this path: "C:\Users\jamal.eclipse\MicroFocus\Student-Record.txt". When I run the code, it asks me the student number, the student tuition owed and the student name but can't see it in my Notepad files. Here's my code:
program-id. Project as "Project".
environment division.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT STUDENT-FILE-IN
ASSIGN TO
"C:\Users\jamal\.eclipse\MicroFocus\Student-Record.txt"
ORGANIZATION IS LINE SEQUENTIAL.
configuration section.
data division.
FILE Section.
FD STUDENT-FILE-IN.
01 STUDENT-RECORD-OUT PIC X(52).
working-storage section.
01 STUDENT-RECORD-IN.
05 STUDENT-NUMBER PIC 9(6).
05 TUITION-OWED PIC 9(6).
05 STUDENT-NAME PIC X(40).
01 PROMPT-MESSAGES-RESPONSES.
05 RECORD-Y-N PIC X(41) VALUE
"Do you have record ? Y or N: ".
05 RESPONSE PIC X(1).
05 STUDENT-NUMBER-OUT PIC X(24) VALUE
"Enter the Student Number: ".
05 TUITION-OWED-OUT PIC X(22) VALUE
"Enter the tuition owed: ".
05 STUDENT-NAME-OUT PIC X(22) VALUE
"Enter your Student Name: ".
procedure division.
CREATE-STUDENT-RECORD-FILE.
PERFORM STUDENT-RECORD-FILE.
PERFORM CREATE-STUDENT-RECORD
UNTIL RESPONSE="N" or "n".
PERFORM T-CREATE-STUDENT-RECORD-FILE.
STOP RUN.
STUDENT-RECORD-FILE.
PERFORM OPEN-RECORD.
PERFORM PROMPT-USER.
CREATE-STUDENT-RECORD.
PERFORM ENTER-STUDENT-DATA.
PERFORM WRITE-STUDENT-RECORD.
PERFORM PROMPT-USER.
T-CREATE-STUDENT-RECORD-FILE.
PERFORM CLS-CREATE-STUDENT-RECORD.
OPEN-RECORD.
OPEN OUTPUT STUDENT-FILE-IN.
PROMPT-USER.
DISPLAY RECORD-Y-N.
ACCEPT RESPONSE.
ENTER-STUDENT-DATA.
DISPLAY STUDENT-NUMBER-OUT.
ACCEPT STUDENT-NUMBER.
DISPLAY TUITION-OWED-OUT.
ACCEPT TUITION-OWED.
DISPLAY STUDENT-NAME-OUT
ACCEPT STUDENT-NAME.
WRITE-STUDENT-RECORD.
MOVE STUDENT-RECORD-IN TO STUDENT-RECORD-OUT.
WRITE STUDENT-RECORD-OUT.
CLS-CREATE-STUDENT-RECORD.
CLOSE STUDENT-FILE-IN.
end program Project.
I'm a beginner to Cobol, thank you in advance for the help.
Here is your program, i made some changes , i hope that will help you
IDENTIFICATION DIVISION.
PROGRAM-ID. project.
environment division.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT STUDENT-FILE-IN
ASSIGN TO "C:\Users\jamal\.eclipse\MicroFocus\Student-Record.txt"
ORGANIZATION IS LINE SEQUENTIAL.
configuration section.
data division.
FILE Section.
FD STUDENT-FILE-IN.
01 STUDENT-RECORD-OUT PIC X(52).
working-storage section.
01 STUDENT-RECORD-IN.
05 STUDENT-NUMBER PIC 9(6).
05 TUITION-OWED PIC 9(6).
05 STUDENT-NAME PIC X(40).
01 PROMPT-MESSAGES-RESPONSES.
05 RECORD-Y-N PIC X(41) VALUE
"Do you have record ? Y or N: ".
05 RESPONSE PIC X(1).
05 STUDENT-NUMBER-OUT PIC X(20) VALUE "Enter Student Number".
05 TUITION-OWED-OUT PIC X(20) VALUE "Enter tuition owed:".
05 STUDENT-NAME-OUT PIC X(20) VALUE "Enter Student Name:".
procedure division.
OPEN OUTPUT STUDENT-FILE-IN.
PERFORM PROMPT-USER.
PERFORM CREATE-STUDENT-RECORD
UNTIL RESPONSE="N" or "n".
PERFORM T-CREATE-STUDENT-RECORD-FILE.
CREATE-STUDENT-RECORD.
PERFORM ENTER-STUDENT-DATA.
PERFORM WRITE-STUDENT-RECORD.
PERFORM PROMPT-USER.
T-CREATE-STUDENT-RECORD-FILE.
PERFORM CLS-CREATE-STUDENT-RECORD.
PROMPT-USER.
DISPLAY RECORD-Y-N.
ACCEPT RESPONSE.
ENTER-STUDENT-DATA.
DISPLAY STUDENT-NUMBER-OUT.
ACCEPT STUDENT-NUMBER.
DISPLAY TUITION-OWED-OUT.
ACCEPT TUITION-OWED.
DISPLAY STUDENT-NAME-OUT
ACCEPT STUDENT-NAME.
WRITE-STUDENT-RECORD.
MOVE STUDENT-RECORD-IN TO STUDENT-RECORD-OUT.
WRITE STUDENT-RECORD-OUT.
CLS-CREATE-STUDENT-RECORD.
CLOSE STUDENT-FILE-IN
STOP RUN.
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
Is it possible to dynamically specify the file name at runtime in a COBOL program?
For example I would like to not have to define the name of a file I would like to open when I write the File-Control section, I would like to read the name of the file I want to open from a different file containing names and I would also like to define(FD) the file I want to open when I pass the name to File-COntrol.
The platform is Unix with Micro Focus Visual Cobol compiler.
I really love it when people ask for help posting a snippet of code that doesn't have a prayer of compiling.
IDENTIFICATION DIVISION.
PROGRAM-ID. STACK-OVERFLOW-1.
AUTHOR. Roland Hughes.
DATE-WRITTEN. TODAY.
DATE-COMPILED. TODAY.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT OPTIONAL OUT_FILE
ASSIGN TO DISK
ORGANIZATION IS SEQUENTIAL
ACCESS MODE IS SEQUENTIAL
FILE STATUS IS IN-STAT.
DATA DIVISION.
FILE SECTION.
FD OUT_FILE
IS GLOBAL
VALUE OF FILE-ID IS OUT_FILE_NAME
LABEL RECORDS ARE STANDARD.
01 DTL-LINE.
03 FIELDA PIC X(14).
03 FIELDB PIC X(10).
03 FIELDC PIC X(32).
03 FIELDD PIC X(03).
03 FIELDE PIC X(02).
WORKING-STORAGE SECTION.
01 STATUS-VARIABLES.
05 IN-STAT PIC X(2).
01 STUFF.
05 OUT_FILE_NAME PIC X(80).
PROCEDURE DIVISION.
MOVE "FILE1.DAT" to OUT_FILE_NAME.
OPEN OUTPUT OUT_FILE.
MOVE SPACES TO DTL-LINE.
MOVE 'HELLO!' TO FIELDA.
WRITE DTL-LINE.
CLOSE OUT_FILE
MOVE "FILE2.DAT" to OUT_FILE_NAME.
OPEN OUTPUT OUT_FILE.
MOVE SPACES TO DTL-LINE.
MOVE 'HI!' TO FIELDB.
WRITE DTL-LINE.
CLOSE OUT_FILE.
MOVE "FILE3.DAT" to OUT_FILE_NAME.
OPEN OUTPUT OUT_FILE.
MOVE SPACES TO DTL-LINE.
MOVE 'FRED' TO FIELDC.
WRITE DTL-LINE.
CLOSE OUT_FILE.
STOP RUN.
I tested this on KDE Neon with all of the latest updates installed. I installed the open-cobol package from the repositories.
cobc -x -free STACK-OVERFLOW-1.COB
./STACK-OVERFLOW-1
roland#roland-HP-EliteDesk-800-G2-SFF:~/COBOL$ ls *.DAT
FILE1.DAT FILE2.DAT FILE3.DAT
roland#roland-HP-EliteDesk-800-G2-SFF:~/COBOL$ cat *.DAT
HELLO! HI! FRED roland#roland-HP-EliteDesk-800-G2-SFF:~/COBOL$
A more complete example:
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT IN_FILE ASSIGN TO IN_FILE
ORGANIZATION IS SEQUENTIAL
ACCESS MODE IS SEQUENTIAL
FILE STATUS IS FSTAT.
FILE SECTION.
FD IN_FILE
VALUE OF ID IS IN_FILE_NAME.
01 IN_POST.
03 FIELDA PIC X(14).
03 FIELDB PIC X(10).
03 FIELDC PIC X(32).
03 FIELDD PIC X(03).
03 FIELDE PIC X(02).
WORKING-STORAGE SECTION.
01 IN_FILE_NAME PIC X(22).
01 FSTAT PIC XX.
PROCEDURE DIVISION.
MOVE "FILE1.DAT" to IN_FILE_NAME
OPEN INPUT IN_FILE
CLOSE IN_FILE
MOVE "FILE2.DAT" to IN_FILE_NAME
OPEN INPUT IN_FILE
CLOSE IN_FILE
MOVE "FILE3.DAT" to IN_FILE_NAME
OPEN INPUT IN_FILE
CLOSE IN_FILE
STOP RUN.
I have a COBOL program that requires a transaction number every run of the program. I am planning to get the last transaction number from the file and add 1 to it. The problem is I don't know how to get the last recorded value.
IDENTIFICATION DIVISION.
PROGRAM-ID. INVENTORY-SYS.
AUTHOR. LINSEY.
DATE-WRITTEN. 2/22/2015.
DATE-COMPILED. 2/22/2015.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT MASTER-FILE ASSIGN TO "inventory-file.txt"
ORGANIZATION IS LINE SEQUENTIAL.
DATA DIVISION.
FILE SECTION.
FD MASTER-FILE.
01 IN-RECORDS.
02 IN-CODE PIC 9(7).
02 IN-NAME PIC X(30).
02 IN-PRICE PIC 9(3).
02 IN-STOCK PIC 9(4).
WORKING-STORAGE SECTION.
01 WS-EOF PIC A(1).
PROCEDURE DIVISION.
100-READ-FILE.
OPEN I-O MASTER-FILE.
PERFORM UNTIL WS-EOF = "Y"
READ MASTER-FILE
AT END
MOVE 'Y' TO WS-EOF
NOT AT END
DISPLAY IN-RECORDS
END-READ
END-PERFORM
CLOSE MASTER-FILE.
STOP RUN.
This is the sample program. The problem is it retrieves all the records from the file I only the last record from "inventory-file.txt"
Well, you are insistent, so:
IDENTIFICATION DIVISION.
PROGRAM-ID. INVENTORY-SYS.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT MASTER-FILE ASSIGN TO "inventory-file.txt"
ORGANIZATION IS LINE SEQUENTIAL
FILE STATUS IS w-if-in-file-status.
DATA DIVISION.
FILE SECTION.
FD MASTER-FILE.
01 IN-RECORDS.
02 IN-CODE PIC 9(7).
02 IN-NAME PIC X(30).
02 IN-PRICE PIC 9(3).
02 IN-STOCK PIC 9(4).
WORKING-STORAGE SECTION.
01 w-if-in-file-status PIC XX.
88 master-file-status-good VALUE ZERO "10".
88 end-of-master-file VALUE "10".
01 w-save-code PIC 9(7).
PROCEDURE DIVISION.
OPEN INPUT MASTER-FILE
[code to check FILE STATUS field]
PERFORM UNTIL end-of-master-file
READ MASTER-FILE
[code to check FILE STATUS field]
MOVE IN-CODE to w-save-code
END-PERFORM
DISPLAY ">" w-save-code "<"
CLOSE MASTER-FILE
[code to check FILE STATUS field]
GOBACK
.
I don't know why your IN-CODE field is numeric. Are you going to do calculations with it?
You keep a Control File. That has a date (to match to the Business Date file) a logical file-name, an environment and the last transaction number.
You maintain that file, checking everything as you do so.
I'm not sure of OpenCobol supports it, but you might try using OPEN/REVERSED. It is an old school way of reading a tape backwards, or these days, a virtual tape. I've no idea if it is implemented, but it is an easy way to read a sequential file backwards.
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.