IBM Mainframe Forum Index
 
Log In
 
IBM Mainframe Forum Index Mainframe: Search IBM Mainframe Forum: FAQ Register
 

Need a logic to validate the data in Detail level record


IBM Mainframe Forums -> COBOL Programming
Post new topic   Reply to topic
View previous topic :: View next topic  
Author Message
sandeep kumar302

New User


Joined: 14 Mar 2012
Posts: 81
Location: India

PostPosted: Mon Feb 01, 2016 3:30 pm
Reply with quote

Hi,

My requirement is-

Valid characters only for detail records positions 31-62 (32 characters in length).Only the following characters should be allowed.
Code:
a.       "a" THRU "z”
b.      "A" THRU "Z"
c.       "0" THRU "9"
d.      " " or blank fill
e.      "."
f.        "&"

All other characters should be replaced with a space character, for example “M’Brien” should be “ M Brien” or “ABC PVT Ltd <Accnt a/c>” should be “ABC PVT Ltd Accnt a c”

Can anyone please help me on this?

Code'd
Back to top
View user's profile Send private message
Bill Woodger

Moderator Emeritus


Joined: 09 Mar 2011
Posts: 7309
Location: Inside the Matrix

PostPosted: Mon Feb 01, 2016 3:54 pm
Reply with quote

In your sample output, you are doing more than just replacing characters by blank.

If that's a typo, an INSPECT ... CONVERTING ... will do what you want. You just list all the characters you don't want, and an equivalent number of spaces for the result.
Back to top
View user's profile Send private message
sandeep kumar302

New User


Joined: 14 Mar 2012
Posts: 81
Location: India

PostPosted: Mon Feb 01, 2016 5:50 pm
Reply with quote

Thanks Bill,

I tried this solution like below:
Code:

INSPECT ACCOUNT-TITLE CONVERTING
        "!@#$%^*()`~,<>/?;:'"[{]}\|" TO
        "                         ".

but it gives me some error as "" is confusing to the compiler.

Code:

  3538     INSPECT ACCOUNT-TITLE CONVERTING
  3539             "!@#$%^*()`~,<>/?;:'"[{]}\|" TO
*  83-S**********************************                              (   0)**
**    Reserved word missing - TO expected.
*   4-S***********************************                             (  62)**
**    Illegal character
*   4-S*************************************                           (  62)**
**    Illegal character
*   4-S**************************************                          (  62)**
**    Illegal character
*   4-S***************************************                         (  62)**
**    Illegal character
*1004-E****************************************************************(  62)**
**    Continuation character expected. End of literal assumed.
  3540             "                         ".

but, when i remove the literal ", the program is compiled successfully like below:

Code:

INSPECT AUD-ACCOUNT-TITLE CONVERTING
        "!@#$%^*()`~,<>/?;:'[{]}\|" TO
        "                         ".
INSPECT AUD-ACCOUNT-TITLE REPLACING  ALL '"' BY " ".


Is there any way i can get the result in single INSPECT as you suggested?
Back to top
View user's profile Send private message
Bill Woodger

Moderator Emeritus


Joined: 09 Mar 2011
Posts: 7309
Location: Inside the Matrix

PostPosted: Mon Feb 01, 2016 6:42 pm
Reply with quote

If you have a quote in a literal, you can bound with apostrophes. If you have an apostrophe in a literal, you can bound with quotes.

If you have both apostrophe and quote in a literal...

You can define in WORKING-STORAGE, and use that as the source of the COVERTING.

You can use a hexadecimal literal.

Slight performance penalty with the former, quite large obfuscation penalty with the latter.
Back to top
View user's profile Send private message
sandeep kumar302

New User


Joined: 14 Mar 2012
Posts: 81
Location: India

PostPosted: Mon Feb 01, 2016 7:33 pm
Reply with quote

Thanks Bill for the prompt reply.

I already tried bounding with apostrophe like below:
Code:

INSPECT AUD-ACCOUNT-TITLE CONVERTING
        "!@#$%^*()`~,<>/?;:'[{]}\|'"'" TO
        "                         ".
INSPECT AUD-ACCOUNT-TITLE REPLACING  ALL '"' BY " ".


But this gave me a compilation error. I am using microfocus cobol.

Actually my motive is not to have anything from the literals
!@#$%^*()`~,<>/?;:'[{]}\| and " also should not be present like abc"xyz..anything like this must be replaced by abc xyz
Back to top
View user's profile Send private message
sandeep kumar302

New User


Joined: 14 Mar 2012
Posts: 81
Location: India

PostPosted: Mon Feb 01, 2016 7:35 pm
Reply with quote

Though i can try the other option which you suggested:

Quote:

You can define in WORKING-STORAGE, and use that as the source of the COVERTING.
Back to top
View user's profile Send private message
Bill Woodger

Moderator Emeritus


Joined: 09 Mar 2011
Posts: 7309
Location: Inside the Matrix

PostPosted: Mon Feb 01, 2016 7:41 pm
Reply with quote

Sorry for not being clear. With both apostrophe and quote in the literal, you can't do it with an ordinary literal.

It has to be defined as data, you'll have to define the separate parts separately.

The only literal you can use is a hex literal, and that would be very obscure and typo-prone.
Back to top
View user's profile Send private message
Bill O'Boyle

CICS Moderator


Joined: 14 Jan 2008
Posts: 2501
Location: Atlanta, Georgia, USA

PostPosted: Mon Feb 01, 2016 7:52 pm
Reply with quote

Please list the characters (in hex) that you need to convert to SPACE. Then, we'll go from there....
Back to top
View user's profile Send private message
Bill O'Boyle

CICS Moderator


Joined: 14 Jan 2008
Posts: 2501
Location: Atlanta, Georgia, USA

PostPosted: Mon Feb 01, 2016 10:52 pm
Reply with quote

Maybe this will do the trick (desk checked only) -
Code:
   
           03  WS-SUB              PIC  9(08)      BINARY.             
           03  WS-SUB-X            REDEFINES WS-SUB                     
                                   PIC  X(04).                         
           03  WS-FWORD            PIC  9(08)      BINARY.             
           03  WS-FWORD-X          REDEFINES WS-FWORD                   
                                   PIC  X(04).                         
           03  AUD-ACCOUNT-TITLE   PIC  X(79).                         
           03  WS-XLATE-TBL-IN     PIC  X(256).                         
           03  WS-XLATE-TBL-OUT    PIC  X(256).                         
                                                                       
           PERFORM VARYING WS-FWORD FROM 1 BY 1                         
               UNTIL WS-FWORD > LENGTH OF WS-XLATE-TBL-IN               
                   COMPUTE WS-SUB      = (WS-FWORD - 1)                 
                   MOVE WS-SUB-X (4:)  TO WS-XLATE-TBL-IN (WS-FWORD:1) 
           END-PERFORM 
      *                                                                 
      **** BUILD THE 'TBL-OUT', MOVING LOWER-CASE AND UPPER-CASE LETTERS
      **** LETTERS AS WELL AS NUMERICS 0-9. FOR EXAMPLE, 130 IS A LOWER
      **** CASE 'b'. BUT, 130 IS THE TBL-OFFSET, WHERE YOU'LL FIND A   
      **** LOWER-CASE 'a'.                                             
      *                                                                 
           MOVE SPACES                 TO WS-XLATE-TBL-OUT             
           MOVE 130                    TO WS-SUB                       
           MOVE WS-XLATE-TBL-IN (WS-SUB:9)                             
                                       TO WS-XLATE-TBL-OUT (WS-SUB:9)   
           MOVE 146                    TO WS-SUB                       
           MOVE WS-XLATE-TBL-IN (WS-SUB:9)                             
                                       TO WS-XLATE-TBL-OUT (WS-SUB:9)   
           MOVE 163                    TO WS-SUB                       
           MOVE WS-XLATE-TBL-IN (WS-SUB:8)                             
                                       TO WS-XLATE-TBL-OUT (WS-SUB:8)   
           MOVE 194                    TO WS-SUB                       
           MOVE WS-XLATE-TBL-IN (WS-SUB:9)                             
                                       TO WS-XLATE-TBL-OUT (WS-SUB:9)   
           MOVE 210                    TO WS-SUB                       
           MOVE WS-XLATE-TBL-IN (WS-SUB:9)                             
                                       TO WS-XLATE-TBL-OUT (WS-SUB:9)   
           MOVE 227                    TO WS-SUB                       
           MOVE WS-XLATE-TBL-IN (WS-SUB:8)                             
                                       TO WS-XLATE-TBL-OUT (WS-SUB:8)   
           MOVE 241                    TO WS-SUB                       
           MOVE WS-XLATE-TBL-IN (WS-SUB:10)                             
                                       TO WS-XLATE-TBL-OUT (WS-SUB:10) 

           INSPECT AUD-ACCOUNT-TITLE   CONVERTING WS-XLATE-TBL-IN       
                                       TO WS-XLATE-TBL-OUT           
      *

By initializing 'TBL-OUT' to SPACES and then, populating 'TBL-OUT' with the characters you'd like to keep, ensures the characters you don't want to keep will equal a SPACE in their respective slots in 'TBL-OUT'.

You may want to consider this as a CALLED sub-program.

HTH....
Back to top
View user's profile Send private message
RahulG31

Active User


Joined: 20 Dec 2014
Posts: 446
Location: USA

PostPosted: Mon Feb 01, 2016 11:31 pm
Reply with quote

If I understand this correctly then having an in-line Perform 32 times for each byte will do. We just have to check for Numeric, Alphabetic, '.' and '&'. I.e. If the byte Is Numeric Or Is Alphateic Or equal to '.' Or '&', then Continue Else move space to that byte.
Back to top
View user's profile Send private message
Bill Woodger

Moderator Emeritus


Joined: 09 Mar 2011
Posts: 7309
Location: Inside the Matrix

PostPosted: Tue Feb 02, 2016 6:27 am
Reply with quote

RahulG31,

That'll be deeply slower than INSPECT. Until necessary (when TS/OP says "yes, I need to entirely remove some bytes") a manual loop is a poor way to do it vs INSPECT.
Back to top
View user's profile Send private message
Rohit Umarjikar

Global Moderator


Joined: 21 Sep 2010
Posts: 3053
Location: NYC,USA

PostPosted: Wed Feb 03, 2016 10:55 pm
Reply with quote

You can also perform a loop till last byte and check each byte and if you find (what you want to replace with space) then move space else move current value and end the loop. Is that what you want?
Ops.. It is the same as what RahulG31 suggested. We have similar in place but never got any substantial performance issues but technically it may be as per Bill.
Back to top
View user's profile Send private message
prino

Senior Member


Joined: 07 Feb 2009
Posts: 1306
Location: Vilnius, Lithuania

PostPosted: Thu Feb 04, 2016 5:27 am
Reply with quote

Sheesh, don't tell me that COBOL doesn't understand that '''' is a single apostrophe and """" a single quote...
Back to top
View user's profile Send private message
Bill Woodger

Moderator Emeritus


Joined: 09 Mar 2011
Posts: 7309
Location: Inside the Matrix

PostPosted: Thu Feb 04, 2016 6:39 am
Reply with quote

The problem is that both apostrophe and quote are wanted in the same literal, and the doubling-up-to-give-one only works for the symbol which bounds the literal.

Code:
"""''" will give "''
'''""' will give '""


So you have to define the field as separate items for at least one of apostrophe/quote, and you can't use a literal (there's no literal concatenation in Enterprise COBOL).

If you get to PIC X VALUE "'" and PIC X VALUE '"', there's no real value in using PIC X VALUE """" or PIC X VALUE ''''.

So you can do it, but not within the same literal, and since you have a choice (these days) of what bounds a literal you just use the other one, I doubt you'll see the doubling-up used in code.
Back to top
View user's profile Send private message
RahulG31

Active User


Joined: 20 Dec 2014
Posts: 446
Location: USA

PostPosted: Fri Feb 05, 2016 12:32 am
Reply with quote

@Bill: The problem I see with the use of INSPECT CONVERTING is that we are restricting ourselves to what we want to convert. To me, this is Not the requirement.

The requirement states what is Valid; Rest all is Invalid. And here, what we are trying to do with INSPECT is, telling what is Invalid and rest all is valid.

We have to make sure that we have all the symbols covered in INSPECT. As of now, I don't see '=, +, -' covered (there may possibly be more), which is error prone.

What TS/OP wants is (as I said earlier) Alphabetic, Numeric, '.' and '&' as Valid and Rest all is Invalid.

IS ALPHABETIC clause covers for capital and small letters as well as space.
IS NUMERIC covers 0-9.

.
Back to top
View user's profile Send private message
Robert Sample

Global Moderator


Joined: 06 Jun 2008
Posts: 8696
Location: Dubuque, Iowa, USA

PostPosted: Fri Feb 05, 2016 2:51 am
Reply with quote

I looked at the original post and came up with this code (for testing I used a second PERFORM against INPUT-DATA-2 but that wouldn't be needed usually):
Code:
       77  STR-POS                 PIC 9(02).         
       77  TEST-CHAR               PIC X(01).         
       77  INPUT-DATA-1            PIC X(32)           
           VALUE "M'BRIEN".                           
       77  INPUT-DATA-2            PIC X(32)           
           VALUE "ABC PVT Ltd <ACCNT A/C>".           
       77  OUTPUT-DATA             PIC X(32).         
       PROCEDURE DIVISION.                             
       0000-START.                                     
           PERFORM                                     
               VARYING STR-POS                         
                   FROM 1 BY 1                         
               UNTIL STR-POS > 32                     
               MOVE INPUT-DATA-1 (STR-POS : 1)         
                                       TO  TEST-CHAR   
               IF  TEST-CHAR ALPHABETIC               
               OR  TEST-CHAR NUMERIC                   
               OR  TEST-CHAR = '.' OR '&'             
                   MOVE INPUT-DATA-1 (STR-POS : 1)     
                     TO OUTPUT-DATA  (STR-POS : 1)     
               ELSE                                   
                   MOVE SPACE                         
                     TO OUTPUT-DATA  (STR-POS : 1)     
               END-IF                                 
           END-PERFORM.                               
           DISPLAY INPUT-DATA-1.                       
           DISPLAY OUTPUT-DATA.                       
           DISPLAY ' ' .                               
                                                       
which produces output of
Code:
M'BRIEN                         
M BRIEN                         
                               
ABC PVT Ltd <ACCNT A/C>         
ABC PVT Ltd  ACCNT A C         
                               
If each character is valid, move it to the output variable character else move a space to that output character. This lets you avoid the whole QUOTE / APOST compiler option mess and ensuing complications.
Back to top
View user's profile Send private message
Bill Woodger

Moderator Emeritus


Joined: 09 Mar 2011
Posts: 7309
Location: Inside the Matrix

PostPosted: Fri Feb 05, 2016 3:18 am
Reply with quote

Well, looking back I see the words Micro Focus COBOL (not spelled correctly).

Don't know if it is Micro Focus for a Mainframe target, or just Micro Focus.
Back to top
View user's profile Send private message
Bill Woodger

Moderator Emeritus


Joined: 09 Mar 2011
Posts: 7309
Location: Inside the Matrix

PostPosted: Sun Feb 07, 2016 5:32 am
Reply with quote

Eek.
Code:

'''"' will get '"
Back to top
View user's profile Send private message
View previous topic :: :: View next topic  
Post new topic   Reply to topic View Bookmarks
All times are GMT + 6 Hours
Forum Index -> COBOL Programming

 


Similar Topics
Topic Forum Replies
No new posts How to save SYSLOG as text data via P... All Other Mainframe Topics 1
No new posts Store the data for fixed length COBOL Programming 1
No new posts How to split large record length file... DFSORT/ICETOOL 10
No new posts SFTP Issue - destination file record ... All Other Mainframe Topics 2
No new posts FINDREP - Only first record from give... DFSORT/ICETOOL 3
Search our Forums:

Back to Top