convert comp-2 to alphanumeric in cobol - cobol

I have a copybook with several COMP-2 variables that I need in alphanumeric form for DISPLAY purposes. I have tried MOVE, REDEFINES, MOVE to numeric then to alphanumeric and nothing seems to work.

Here's a program:
ID DIVISION.
PROGRAM-ID DISPLEXP.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 SOME-NAME COMP-2.
01 SOME-OUTPUT PIC -9.9E-99.
PROCEDURE DIVISION.
MOVE -2.3E-6 TO SOME-NAME
SOME-OUTPUT
DISPLAY
">"
SOME-NAME
"<"
">"
SOME-OUTPUT
"<"
GOBACK
.
The output is:
>-.23000000000000000E-05<>-2.3E-06<
If you can clarify your question, I'm sure there's an answer available.

Related

Using a translate API to convert from Cobol or gnucobol to other language

I am looking for an example using Cobol either mf cobol or gnucobol. I would like an alternate of VB or C. Old time coboller since Cobol 61. I have looked at the Java and python examples but they are not clear to me.
Parameter sizes, contents, and order are what I am looking for as well as the translation routine or module name.
Vb or c example will do as I have worked with those languages as well.
A cobol example with results expected:
Id division.
Program-Id. Somename.
Environment division.
Data division.
Working-storage section.
01 Some-existing-text pic x(32000) value
"The quick brown fox jumped over the silver moon".
01 input-text-type pic x(20) value "english".
01 resulting-text pic x(32000) value
"Der schnelle braune Fuchs sprang über den silbernen Mond ".
01 destination-text-type pic x(20) value "German".
Procedure division.
Start-here.
Call "translation-routine" using Some-existing-text,
input-text-type,
Resulting-text,
Destination-text-type.
Stop-here.
Stop run.
Take a look at this, i tried it in linux and its working absolutely fine.
First Install Translate Shell:-
Translate Shell is available in the official repositories of popular Linux operating systems.
Use below command to install.
$ sudo apt-get install translate-shell
Now find the cobol code that takes user input and translates from your preferred language to English and vice versa.
ID DIVISION.
PROGRAM-ID. SOMENAME.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 SOME-SAMLPLE-TEXT PIC X(30) VALUE "नमस्ते". /*THIS WORD IS "HI" IN HINDI*/
PROCEDURE DIVISION.
START-HERE.
STRING "TRANS"
" "
SOME-SAMLPLE-TEXT
DELIMITED BY SPACES INTO LINUX-COMMAND.
CALL "SYSTEM" USING LINUX-COMMAND
RETURNING CONVERTED-TEXT.
DISPLAY CONVERTED-TEXT.
STOP RUN.
Output will be "HI"
Below program translates Hindi to Tamil, you can use an variable and make the language code dynamic.
For more language codes goto:https:language codes
ID DIVISION.
PROGRAM-ID. SOMENAME.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 SOME-SAMPLE-TEXT PIC X(30) VALUE "नमस्ते". /*THIS WORD IS "HI" IN HINDI*/
PROCEDURE DIVISION.
START-HERE.
STRING "TRANS"
" "
":"
"te" /*code to convert text to tamil*/
" "
SOME-SAMPLE-TEXT
DELIMITED BY SPACES INTO LINUX-COMMAND.
CALL "SYSTEM" USING LINUX-COMMAND
RETURNING CONVERTED-TEXT.
DISPLAY CONVERTED-TEXT.
STOP RUN.
Output will be "வணக்கம்"
For information on installing google translate in linux please refer :this link
Happy coding........

How to use LINKAGE SECTION and WORKING-STORAGE SECTION in the same file?

I'm trying to write a COBOL module and having some variables in this file too:
IDENTIFICATION DIVISION.
PROGRAM-ID. UTIL.
DATA DIVISION.
LINKAGE SECTION.
01 MY_VAR PIC X(100).
DATA DIVISION.
WORKING-STORAGE SECTION.
01 RESULT PIC X(200) value SPACES.
PROCEDURE DIVISION USING MY_VAR.
STRING INPUT DELIMITED BY SPACE
' ' DELIMITED BY SIZE
MY_VAR BY SPACE
INTO RESULT
DISPLAY RESULT
EXIT PROGRAM.
For the input argument (MY_VAR) I use LINKAGE SECTION. I'm not sure how to use the WORKING-STORAGE SECTION statement to declare the RESULT variable.
How can I do that?
You should have 1 Data Division. Also, I think the order is not good for the Sections.
I advise looking at some Cobol documentation before coding.
IDENTIFICATION DIVISION.
PROGRAM-ID. UTIL.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 RESULT PIC X(200) value SPACES.
LINKAGE SECTION.
01 MY_VAR PIC X(100).
PROCEDURE DIVISION USING MY_VAR.
STRING INPUT DELIMITED BY SPACE
' ' DELIMITED BY SIZE
MY_VAR BY SPACE
INTO RESULT
DISPLAY RESULT
EXIT PROGRAM.
Are you using Cobol program on the mainframe of PC? If on PC - which Cobol program are you using?
If you are using a linkage section, first 2 bytes specify the length of the variable.
Also - I don't see the definition of the INPUT variable, unless INPUT is some kind of Cobol command (not recognized on the mainframe computers).
The correct syntax (on the mainframe) is:
LINKAGE SECTION.
01 link-parms.
05 LNK-PARM-LENGTH PIC S9999 COMP.
05 MY_VAR PIC X(100).
PROCEDURE DIVISION USING MY_VAR.
STRING INPUT DELIMITED BY SPACE
' ' DELIMITED BY SIZE
MY_VAR BY SPACE
INTO RESULT
DISPLAY RESULT
STOP RUN.

Moving hexadecimal to a comp declared variable in cobol

Is it possible to assign a string of hexadecimal to a comp or binary declared variable?
Example:
01 COMP-VAR PIC 9(4) COMP.
MOVE X'04D2' TO COMP-VAR.
should output +1234.
Edited:
Sorry for the lack of the information, I just gave an example. The real scenario is that the data will come from an external source, a dataset. I need to store the data in an alphanumeric variable before I move it to a comp declared variable. My problem is that the data is incorrect when I move the alphanumeric data to the comp variable. Your help is very much appreciated.
I think you are looking for REDEFINES. Redefine the binary value as character, do the assignment
which will not violate any of the assignment rules and then use the binary representation in
subsequent operations. This program illustrates your example:
IDENTIFICATION DIVISION.
PROGRAM-ID. EXAMPLE.
DATA DIVISION.
WORKING-STORAGE SECTION.
01.
02 COMP-VAR PIC 9(4) COMP.
02 COMP-X REDEFINES COMP-VAR PIC X(2).
PROCEDURE DIVISION.
MOVE X'04D2' TO COMP-X
DISPLAY COMP-VAR
GOBACK
.
This displays 1234.
The larger question is why would you need to do this? I suspect that you are attempting to
read a file with multiple record formats in it. Based on some common record identifier you
need to read part of the record as character or as binary. Typically this is done a little
differently in COBOL.
Here is a larger example of what I mean. Suppose you have an input
record that is 3 bytes long. When the first byte is a 'B' it is telling you that the next two bytes should be
treated as a binary (COMP) value. When the first byte is an 'X' you need to read the next two
bytes as text (X) data. As an example this is what two records might look like:
X'E7C1C2'
X'C204D2'
The first record is a text record containing the value 'AB' (EBCDIC). The second record is binary containing
the value 1234. The program to process these records might look something like:
IDENTIFICATION DIVISION.
PROGRAM-ID. EXAMPLE.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 INPUT-RECORD.
02 REC-TCD PIC X.
88 REC-TCD-BIN VALUE 'B'.
88 REC-TCD-CHAR VALUE 'X'.
02 REC-DUMMY PIC X(2).
02 REC-COMP-VAR REDEFINES REC-DUMMY PIC 9(4) BINARY.
02 REC-CHAR-VAR REDEFINES REC-DUMMY PIC X(2).
PROCEDURE DIVISION.
*
* THIS IS A CHARACTER RECORD
*
MOVE X'E7C1C2' TO INPUT-RECORD
PERFORM DISPLAY-INPUT-RECORD
*
* THIS IS A BINARY RECORD
*
MOVE X'C204D2' TO INPUT-RECORD
PERFORM DISPLAY-INPUT-RECORD
GOBACK
.
DISPLAY-INPUT-RECORD.
EVALUATE TRUE
WHEN REC-TCD-BIN
DISPLAY 'REC TYPE: ' REC-TCD
' BINARY DATA: ' REC-COMP-VAR
WHEN REC-TCD-CHAR
DISPLAY 'REC TYPE: ' REC-TCD
' CHAR DATA : ' REC-CHAR-VAR
WHEN OTHER
DISPLAY 'UNKNOWN RECORD TYPE: ' REC-TCD
END-EVALUATE
.
The output from this program is:
******************************** Top of Data ***********************************
REC-TYPE: X CHAR DATA : AB
REC-TYPE: B BINARY DATA: 1234
******************************* Bottom of Data *********************************
Look at the INPUT-RECORD definition. The first byte determines how the rest of the
record is to be intrepreted. REC-DUMMY is generally defined as a "generic" buffer area
to be subsequently redefined. In the case of variable length input records, REC-DUMMY
is defined to be as long as the longest record variant so the subsequent REDEFINEs of it
do not "upset" the compiler. All data items following REC-DUMMY begin with the same level
number (02 in the example) and REDEFINE it to the the appropriate format. Subsequent
processing uses whatever record redefinition is appropaiate based on the value in REC-TCD.

Is there a way to use INSPECT TALLYING with a check for multiple characters?

I have a string for which I wish to tally the count of characters till a certain pattern of characters is found.
For example:
Give a string: askabanskarkartikrockstar
I would like to know how many characters are there before the kartik in the string.
In a normal scenario where I need to find the number of characters before, say k, in the given string, I would write the code somewhat as:
INSPECT WS-INPUT-STRING TALLYING CT-COUNTER FOR CHARACTERS BEFORE LT-K
Where
WS-INPUT-STRING is alphanumeric with a value of
askabanskarkartikrockstar,
CT-COUNTER is the counter used to count the number of characters
LT-K is a literal with the value k.
But here, if I wish to do the same for a sub-string, like kartik in the above example, would replacing the value of LT-K with kartik instead of just k work? If yes, is the same applicable for alphanumeric literals that have values in the form of hexadecimal numbers (for example, in a literal X(02) one stores a new-line character as x'0D25')?
I'm trying to implement the above code in zOS IBM mainframe v10. Thanks.
You have pretty much answered your own question... The answer is yes you can do this. Here is a working example program:
IDENTIFICATION DIVISION.
PROGRAM-ID. EXAMPLE.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-INPUT-STRING PIC X(80).
01 WS-COUNTER PIC 9(4).
01 WS-TAG PIC X(10).
PROCEDURE DIVISION.
MAIN-PARAGRAPH.
MOVE 'askabanskarkartikrockstar' TO WS-INPUT-STRING
MOVE ZERO TO WS-COUNTER
MOVE 'kartik' TO WS-TAG
INSPECT WS-INPUT-STRING
TALLYING WS-COUNTER
FOR CHARACTERS BEFORE WS-TAG(1:6)
DISPLAY WS-COUNTER
GOBACK
.
WS-COUNTER displays as 11, there are 11 characters before the WS-TAG string.
Notice that I defined WS-TAG as PIC X(10). This variable is longer than the actual tag value you are looking for. To prevent the INSPECT verb from trying to match on trailing spaces introduced by:
MOVE 'kartik' TO WS-TAG
I had to specify a reference modified value for INSPECT to search for. Had I simply used:
FOR CHARACTERS BEFORE WS-TAG
without reference modification, WS-COUNTER would have been 80 - the length of WS-INPUT-STRING. This is because the string 'kartik ' is not found and the counter tallies the length of the entire input string.
Another approach would be to specify the tag as a literal:
FOR CHARACTERS BEFORE 'kartik'
You can move hexadecimal constants into PIC X fields as follows:
MOVE X'0D25' TO WS-TAG
This occupies 2 characters so you would use WS-TAG(1:2) when INSPECTing it.
If you want to do "a lot" of this at once, then you'll find a PERFORM VARYING will be faster. It is more typing, and you have to think more, and there is more chance for error. But once you have one working, you just have to copy the code to reuse it.

SUBSTRING for a String Literal in COBOL

Is there anyway to get a SUBSTRING of string literal in COBOL without using a temporary variable?
Let's say in the following code:
MOVE "HELLO" TO MY-VAR.
MOVE MY-VAR(1:3) TO SUB-STR.
Is there any way to do the same thing, but without MY-VAR?
EDIT:
I did tried following code, but it's failed.
MOVE "HELLO"(1:3) TO SUB-STR * COMPILE ERROR
You can accomplish what you are trying to do by type-laundering the literal through a function. You can then substring, or reference modify, the output of the function. Consider that calling reverse twice on the same data returns the original data.
Move function reverse
( function reverse(
'abcdefg'
)
) (3:1) to text-out
The above will result in a 'c' being moved to text-out.
Of course, the example code in your question does not make any sense, as why would you write "HELLO"(1:3) when you could just write "HEL".
So you must be wanting to use a variable (or 2) in the reference modifier field(s).
If you are wanting to get the first 'N' characters of the literal, you can do this by using the reference modifier on the destination item. For example, if you compile and run the following program:
IDENTIFICATION DIVISION.
PROGRAM-ID. HELLO.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 LEN PIC 99 VALUE 8.
01 SUB-STR PIC X(80).
PROCEDURE DIVISION.
MOVE "HELLO WORLD" TO SUB-STR(1:LEN).
DISPLAY SUB-STR.
STOP RUN.
You get the resulting output:
HELLO WO
Unfortunately this method only works if you want the first 'N' characters of the literal string.
Also, the destination string must be empty before you start. In the above program, if you changed the definition of SUB-STR to be:
01 SUB-STR PIC X(80) VALUE "BLAH BLAH BLAH".
Then the result of running the program becomes:
HELLO WOH BLAH
Put the "literal" into a field, like a constant.
IDENTIFICATION DIVISION.
PROGRAM-ID. HELLO.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 LITERAL-HELLO PIC X(5) VALUE 'HELLO'.
PROCEDURE DIVISION.
DISPLAY LITERAL-HELLO(1:3).
STOP RUN.

Resources