Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 7 years ago.
Improve this question
SO I am learning COBOL for my job. This is my first program and I am already stuck
The aim of my program is to accept the name and date and display it.
The code is as such
IDENTIFICATION DIVISION.
PROGRAM-ID. PROG.
DATA DIVISION.
WORKING-STORAGE SECTION.
77 NAME PIC X(6)
PROCEDURE DIVISION.
DISPLAY 'Enter name(6 char max)'.
ACCEPT NAME.
DISPLAY 'Name is',NAME.
DISPLAY 'Date is', DATE.
STOP RUN.
I am using this compiler http://www.tutorialspoint.com/compile_cobol_online.php and getting this error
sh-4.3$ cobc -x -free *.cobc -o main
main.cobc:6: Error: syntax error, unexpected PROCEDURE, expecting EXTERNAL or GLOBAL
Any idea?
Every line but one has a period (the line before your error)
Plus, I'll point you back to your own referenced website : http://www.tutorialspoint.com/cobol/cobol_program_structure.htm
Here is compiled code:
.(dot) missed after X(6) and indentation also matters.
IDENTIFICATION DIVISION.
PROGRAM-ID. PROG.
DATA DIVISION.
WORKING-STORAGE SECTION.
77 NAME PIC X(6).
PROCEDURE DIVISION.
DISPLAY 'Enter name(6 char max)'.
ACCEPT NAME.
DISPLAY 'Name is ', NAME.
DISPLAY 'Date is ', FUNCTION CURRENT-DATE.
STOP RUN.
Related
I started to learn Cobol a few days ago and I'm wathcing a video about the basics. The problem that I have is that i'm calling a rountine from another file and when I compile the program I get the error libcob: module 'GETSUM' not found.
I'm using a virtual machine with wsl2 wIth ubuntu 20.04.4 LTS on windows 10. And as compiler I am using GnuCobol 2.2.0
Code of main file :
IDENTIFICATION DIVISION.
PROGRAM-ID. COBOL-TUTORIAL5.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 Num1 PIC 9 VALUE 5.
01 Num2 PIC 9 VALUE 4.
01 Sum1 PIC 99.
PROCEDURE DIVISION.
CALL 'GETSUM' USING Num1, Num2, Sum1.
DISPLAY Num1 " + " Num2 " = " Sum1.
STOP RUN.
Get sum file:
IDENTIFICATION DIVISION.
PROGRAM-ID. GETSUM.
DATA DIVISION.
LINKAGE SECTION.
01 LNum1 PIC 9 VALUE 5.
01 LNum2 PIC 9 VALUE 4.
01 LSum PIC 99.
PROCEDURE DIVISION USING LNum1, LNum2, LSum,.
ADD LNum1 TO LNum2 GIVING LSum.
EXIT PROGRAM.
when I compile the program I get the error libcob: module 'GETSUM' not found
That can't be the case, because this is the COBOL runtime telling you the module is missing, so this only happens when executing, not when compiling.
You have two general options:
cobc -x COBOL-TUTORIAL5.cob GETSUM.cob
--> compile everything at once, creating one big binary. In this case you may want to add -static for both faster runtime and for making sure that you indeed include everything necessary (if not you'd get a linker error, commonly a message like "symbol 'GETSUM' not found").
Compile at least GETSUM.cob as module (cobc GETSUM.cob) and have it either in the current directory when COBOL-TUTORIAL5, or use COB_LIBRARY_PATH to point to the place where the modules are located.
For more details see the GnuCOBOL manual using Multiple source.
What am I doing wrong with the following piece of code under GnuCOBOL 3.1-rc1.0?
IDENTIFICATION DIVISION.
PROGRAM-ID. NUMTEST.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 NUM PIC 999V99.
PROCEDURE DIVISION.
DISPLAY "ENTER NUMBER: ".
ACCEPT NUM.
DISPLAY "NUMBER = ".
DISPLAY NUM.
STOP RUN.
I enter 123.45 as my input. I'm expecting 123.45 as the output, but instead I get 123.40
These are plain ACCEPTs, they only read in data from the command line (you can also enter a big lorem ipsum there).
While I think it is a reasonable request to have this working "as expected" the best option you currently have is ACCEPTing only PIC X and then use MOVE FUNCTON NUMVAL (INPUT-DATA) TO NUM (maybe test the data with FUNCTION TEST-NUMVAL() before). For DISPLAY you likely want an edited field with a PICTURE like ZZ9.99.
In any case: be aware that V is an implied decimal point, it is not part of the actual storage.
Using "extended" screenio (= input not from the command line) gives some benefits (like only allowing numeric data and not more than the fields's size) but has different culprits (for example you should use COLUMN/LINE for it and numeric ACCEPT still has some issues in GC 3.1).
As suggested by JoelFan I've tested edited fields - these work currently only correctly when in "command line mode" (so not if any attributes like positioning is used):
PROGRAM-ID. NUMTEST.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 NUM-INP PIC 999.99.
01 NUM PIC 999V99.
01 NUM-OUT PIC zz9.99.
PROCEDURE DIVISION.
DISPLAY "ENTER NUMBER: ".
ACCEPT NUM-INP.
DISPLAY "NUMBER = ".
MOVE NUM-INP TO NUM
MOVE NUM TO NUM-OUT
DISPLAY NUM "/" NUM-OUT.
STOP RUN.
Producing the expected result:
ENTER NUMBER:
123.45
NUMBER =
123.45/123.45
ENTER NUMBER:
1.2
NUMBER =
001.20/ 1.20
ENTER NUMBER:
a
NUMBER =
000.00/ 0.00
ENTER NUMBER:
1234567
NUMBER =
567.00/567.00
Note: the third case should actually raise an exception when compiled with -fec=all / -debug (currently doesn't), the last case is completely correct as numbers are right justified.
Still: ACCEPTing alphanumeric data, do explicit checks/conversions, and display as edited field like NUM-OUT above is the safest option.
From my understanding when using UNSTRING, the use of ON OVERFLOW [INSTRUCTION] will be useful if there would be an overflow in the use of the UNSTRING.
But if there is no overflow, why would you use NOT ON OVERFLOW [INSTRUCTION] ?
The only possible utility to the NOT ON OVERFLOW [INSTRUCTION] would be to pass an instruction if there is no overflow but what would be the use of that if you already had the expected result from the UNSTRING ?
Is there any concrete example of how this could be useful in this example :
IDENTIFICATION DIVISION.
PROGRAM-ID. YOUR-PROGRAM-NAME.
DATA DIVISION.
FILE SECTION.
WORKING-STORAGE SECTION.
01 WS-VAR1 PIC A(11) VALUE "Hello World".
01 WS-VAR2 PIC A(5).
01 WS-VAR3 PIC A(5).
01 WS-COMPTEUR PIC 9 VALUE 2.
PROCEDURE DIVISION.
MAIN-PROCEDURE.
INTO WS-VAR2 WS-VAR3
WITH POINTER WS-COMPTEUR
ON OVERFLOW DISPLAY "This string is too large"
END-UNSTRING.
DISPLAY WS-VAR2
DISPLAY WS-VAR3.
STOP RUN.
END PROGRAM YOUR-PROGRAM-NAME.
Even when I read IBM documentation, it doesn't give me much explanation as to what could be used in this instance but to display a message ?
IBM Documentation : link
From my understanding when using UNSTRING, the use of ON OVERFLOW
phrase will be useful if there would be an overflow in the use
of the UNSTRING.
But if there is no overflow, why would you use NOT ON OVERFLOW
phrase ?
The only possible utility to the NOT ON OVERFLOW phrase would
be to pass an instruction if there is no overflow but what would be
the use of that if you already had the expected result from the
UNSTRING ?
In COBOL 74 there was no NOT ON OVERFLOW phrase. Therefore, it was necessary to use either a GO TO statement or set a flag for testing in an immediately following IF statement. The NOT ON OVERFLOW phrase and END-UNSTRING were added in COBOL 85 to to improve program structure.
For your example, I made some changes to first display WS-VAR1 then the result of the UNSTRING. Note that the OVERFLOW condition concerns the number of items and not the length of the text. I ran three tests to show the results
IDENTIFICATION DIVISION.
PROGRAM-ID. YOUR-PROGRAM-NAME.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-VAR1 PIC A(11) VALUE "Hello World".
01 WS-VAR2 PIC A(5).
01 WS-VAR3 PIC A(5).
PROCEDURE DIVISION.
MAIN-PROCEDURE.
MOVE SPACE TO WS-VAR2 WS-VAR3
DISPLAY WS-VAR1
UNSTRING WS-VAR1
DELIMITED SPACE
INTO WS-VAR2 WS-VAR3
ON OVERFLOW
DISPLAY
"Incorrect number of items in WS-VAR1 - expected 2"
NOT ON OVERFLOW
DISPLAY WS-VAR2
DISPLAY WS-VAR3
END-UNSTRING
STOP RUN.
END PROGRAM YOUR-PROGRAM-NAME.
Results:
Hello World
Hello
World
--
Hello
Incorrect number of items in WS-VAR1 - expected 2
--
Hello W rld
Incorrect number of items in WS-VAR1 - expected 2
As may be seen in the code, ON OVERFLOW is used for error processing; NOT ON OVERFLOW is used for normal processing. Without the improved structure from NOT ON OVERFLOW, normal processing would immediately follow the error processing, unless one used the previously mentioned COBOL 74 type processing.
Note that DELIMITED ALL SPACE gives a different result than that shown for one case, above. [Ignore the --]
--
Hello
Hello
--
You can use the "NOT ON OVERFLOW " statement if you need to call a PROCEDURE to validate this sentence for example SORT-COLORS.
MOVE 0 TO COUNT-1.
UNSTRING COLOR-LIST
DELIMITED BY ":" OR "/" OR ALL SPACE
*DELIMIT-1 and COUNT-1 will hold only
*the values associated with COLOR-1.
INTO COLOR-1
DELIMITER IN DELIMIT-1
COUNT IN COUNT-1,
COLOR-2,
COLOR-3,
COLOR-4
ON OVERFLOW
DISPLAY "overflow: unstring colors"
NOT ON OVERFLOW
*do when UNSTRING succeeds.
PERFORM **SORT-COLORS**
END-UNSTRING.
*COLOR-1 = "RED "
*COLOR-2 = "BLUE "
*COLOR-3 = "GREEN "
*COLOR-4 = "YELLOW"
*DELIMIT-1 = ": "
*COUNT-1 = 3 count-1 holds the number of characters in RED
You can see more examples on this link https://supportline.microfocus.com/documentation/acucorpproducts/docs/v6_online_doc/gtman3/gt36141.htm
On practice if youy need to discovery if your command(unsting) are executed with sucess withou a IF you can use this statement to define it.
An example using your aplication
IDENTIFICATION DIVISION.
PROGRAM-ID. YOUR-PROGRAM-NAME.
DATA DIVISION.
FILE SECTION.
WORKING-STORAGE SECTION.
01 WS-VAR1 PIC A(11) VALUE "Hello World".
01 WS-VAR2 PIC A(5).
01 WS-VAR3 PIC A(5).
01 WS-COMPTEUR PIC 9 VALUE 2.
PROCEDURE DIVISION.
MAIN-PROCEDURE.
INTO WS-VAR2 WS-VAR3
WITH POINTER WS-COMPTEUR
ON OVERFLOW
PERFORM RT-SEND-ERROR-MAIL
NOT ON OVERFLOW
PERFORM RT-SEND-SUCESS-MAIL
END-UNSTRING.
DISPLAY WS-VAR2
DISPLAY WS-VAR3.
STOP RUN.
END PROGRAM YOUR-PROGRAM-NAME.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
Problem:
If the inventory total is less than 50, add a string of two asterisks (**) at the end of the written row to notify the inventory manager that more inventory is needed. If the inventory total is less than 10, add a string of five asterisks (*****) at the end of the row to let the inventory manager know the need for more inventory is urgent.
How would I make a string of asterisks in Cobol?
How would I make a string of asterisks in Cobol?
There are two methods.
The first controls the number of characters at the destination and works best when the data item is initialized before the move. The second controls the number of characters at the source and works best when initialization of the destination is of no concern or when used as part of a STRING statement.
Method 1:
move all "*" to data-name-1 (1:number-of-asterisks)
For example:
program-id. aster.
data division.
working-storage section.
1 n pic 99.
1 asterisk-line pic x(10) value space.
procedure division.
begin.
perform varying n from 10 by -1 until n < 1
move all "*" to asterisk-line (1:n)
display asterisk-line
move space to asterisk-line
end-perform
stop run
.
Output:
**********
*********
********
*******
******
*****
****
***
**
*
Notice that the program moves spaces to clear the destination after displaying the asterisks. This is prevent too many asterisks from showing on the following lines.
Method 2:
move asterisks (1:number-of-asterisks) to data-name-1
For example:
program-id. aster2.
data division.
working-storage section.
1 n pic 99.
1 asterisks pic x(10) value all "*".
1 asterisk-line pic x(10) value space.
procedure division.
begin.
perform varying n from 10 by -1 until n < 1
move asterisks (1:n) to asterisk-line
display asterisk-line
end-perform
stop run
.
The output is the same as above.
Notice there is no need to move spaces (or initialize) the destination before moving the asterisks.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I am working with GnuCOBOL(Using Windows) and I need to write a compiler with it.
What i am asking is - given directory path, can i modify the files inside of it
using COBOL? It is important to say that you can't know the files names. You know only the path of the directory which contains them.
Here is some code for POSIX systems
identification division.
program-id. SAMPLE.
environment division.
configuration section.
repository.
function all intrinsic.
data data division.
working-storage section.
01 dir usage pointer.
01 dent usage pointer.
01 dirent based.
05 filler pic x(19). *> HERE BE DRAGONS
05 entname pic x(256).
05 filler pic x(237).
01 sayname pic x(256).
*> ************************************************
code procedure division.
call "opendir" using
by content z"."
returning dir
on exception
display "error: no opendir found" upon syserr end-display
bail stop run returning 1
end-call
if dir not equal null then
call "readdir" using
by value dir
returning dent
end-call
perform until dent equal null
*> set address of the based dirent and pull out the name
set address of dirent to dent
initialize sayname
string entname delimited by x"00" into sayname end-string
display trim(sayname TRAILING) end-display
call "readdir" using
by value dir
returning dent
end-call
end-perform
call "closedir" using by value dir end-call
else
call "perror" using by content z"" returning omitted end-call
bail stop run returning 1
end-if
done goback.
end program SAMPLE.
Originally posted to SourceForge, licensed under the GPL. Due to the assumption on sizing of dirent you'd want to duff the code over a little bit before unleashing it on the unwary.