×
INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!
  • Students Click Here

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Students Click Here

Removing spaces form a Message

Removing spaces form a Message

Removing spaces form a Message

(OP)
I have a i/p message line,consisting of some writing,some nos.etc. Now, anywhere in the msg there can be more than one space. I want to remove the spaces to one space if the
spaces are not at starting,or if its at staring then I
dont need any space.
for eg.
'a/c balace is $200.00      name    is    smith' sholud be
''a/c balace is $200.00 name is smith'

and if
'    'a/c balace is      $200.00',I need it to be
'a/c balace is $200.00'

Please suggest me a way out.
 
   
 

RE: Removing spaces form a Message

...or have a look at the INSPECT statement to replace two spaces by one. If you want to replace multiple spaces by one you could use INSPECT in a loop.

RE: Removing spaces form a Message

(OP)
How to use the INSPECT loop? can u write a scribble that?it would b helpful...

RE: Removing spaces form a Message

INSPECT has REPLACING, CONVERTING and TALYING, but with REPLACING you can replace only some definite characters with another, e.g.
INSPECT MY-STRING REPLACING ALL 'XY' BY 'AB'
or

CODE

INSPECT MY-STRING REPLACING ALL SPACE BY '*'
But then you will get for example instead of

CODE

'a/c balace is $200.00      name    is    smith'
this

CODE

'a/c*balace*is*$200.00******name****is****smith'
and this si not, what we need - we want reduce all spaces to one space only.
I don't know if this can be done simply with INSPECT, but instead of exploring the INSPECT alchemy you can code your own algorithm, like this

CODE

       IDENTIFICATION DIVISION.
       PROGRAM-ID.                  RMVSPACES.
       AUTHOR.                      MIKROM.
       ENVIRONMENT DIVISION.

       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 MY-INPUT-STRING          PIC X(200)
              VALUE 'a/c balace is $200.00      name    is    smith'.
       01 MY-OUTPUT-STRING         PIC X(200).

       01 WS-FIELDS.
          05 WS-DATA                     PIC X(200).
          05 WS-DATA-LENGTH              PIC 9(3).
          05 X                           PIC 9(3).
          05 J                           PIC 9(3).
          05 K                           PIC 9(3).
          05 N                           PIC 9(3).
          05 S                           PIC 9(3).

       PROCEDURE DIVISION.
       MAIN.
           INITIALIZE WS-FIELDS

           MOVE MY-INPUT-STRING TO WS-DATA
           PERFORM COMPUTE-LENGTH-OF-THE-DATA
           DISPLAY 'MY-INPUT-STRING = '
                    QUOTE
                    MY-INPUT-STRING(1:WS-DATA-LENGTH)
                    QUOTE
           END-DISPLAY
           DISPLAY 'LENGTH OF STRING = ' WS-DATA-LENGTH

           PERFORM FORMAT-STRING-WITH-SPACES

           PERFORM COMPUTE-LENGTH-OF-THE-DATA
           MOVE WS-DATA TO MY-OUTPUT-STRING
           DISPLAY 'MY-OUTPUT-STRING = '
                    QUOTE
                    MY-OUTPUT-STRING(1:WS-DATA-LENGTH)
                    QUOTE
           END-DISPLAY
           DISPLAY 'LENGTH OF STRING = ' WS-DATA-LENGTH

      *    End
           GOBACK
           .

       COMPUTE-LENGTH-OF-THE-DATA.
           COMPUTE X = 0.
           INSPECT FUNCTION REVERSE(WS-DATA)
           TALLYING X
           FOR LEADING SPACES.
           COMPUTE WS-DATA-LENGTH = LENGTH OF WS-DATA - X
           .

       FORMAT-STRING-WITH-SPACES.
           MOVE WS-DATA-LENGTH TO N
           PERFORM VARYING J FROM 1 BY 1 UNTIL J > N
             IF WS-DATA(J : 1) = SPACE AND WS-DATA(J + 1 : 1) = SPACE
               COMPUTE J = J + 1
               MOVE J TO K
      *        S - number of superfluous Spaces
               INITIALIZE S
      *        Search from position J+1 for Not-Space-Characters
               PERFORM UNTIL WS-DATA(K:1) NOT = SPACE
                 ADD 1 TO K
                 ADD 1 TO S
               END-PERFORM
      *        Shift substring left from position K to J
               MOVE WS-DATA(K : N - K + 1) TO WS-DATA(J : N - K + 1)
      *        Adjust new length
               COMPUTE N = N - S
      *        Clear last characters in String
               MOVE SPACE TO WS-DATA(N + 1 : S)
             END-IF
           END-PERFORM
           MOVE N TO WS-DATA-LENGTH
           .

Output

CODE

> call rmvspaces                                           
  MY-INPUT-STRING = 'a/c balace is $200.00      name    is
    smith'                                                 
  LENGTH OF STRING = 046                                   
  MY-OUTPUT-STRING = 'a/c balace is $200.00 name is smith'
  LENGTH OF STRING = 035                                   

  

RE: Removing spaces form a Message

@mikrom: you're right of course. INSPECT ... REPLACING cannot be used in this case.

RE: Removing spaces form a Message

I have a subroutine in COBOL which does three things with a string of up to 999 bytes: 1), converts the case to upper, lower or title (or no conversion), 2) Justifies the string left, right or center (or no justification), 3) tests the string for caracters outside the range of 32 (space) through 126 (~), or 0-9, A-Z.

RE: Removing spaces form a Message

Since we're posting programs now:

CODE

 IDENTIFICATION DIVISION.
 PROGRAM-ID. REMSPACES.
 ENVIRONMENT DIVISION.
 DATA DIVISION.
 WORKING-STORAGE SECTION.
 01  INPUT-VARIABLES.
     04  INPUT-STRING1             PIC X(80) VALUE
         "a/c balace is $200.00      name    is    smith".
     04  INPUT-STRING2             PIC X(80) VALUE
         "    a/c balace is      $200.00".
 01  PROCESSING-VARIABLES.
     04  PROC-STRING               PIC X(80).
     04  PARTS-WHOLE.
         08  PARTS-TABLE           PIC X(20) OCCURS 9 TIMES INDEXED BY PARTS-NDX.
     04  SPACE-COUNT               PIC S9(4) BINARY.
 01  OUTPUT-VARIABLES.
     04  OUTPUT-STRING             PIC X(80).

 PROCEDURE DIVISION.
 0000-MAIN SECTION.
     MOVE INPUT-STRING1 TO PROC-STRING.
     DISPLAY " INPUT: " PROC-STRING.
     PERFORM 1000-PROC-STR.
     DISPLAY "OUTPUT: " OUTPUT-STRING.
     DISPLAY " ".

     MOVE INPUT-STRING2 TO PROC-STRING.
     DISPLAY " INPUT: " PROC-STRING.
     PERFORM 1000-PROC-STR.
     DISPLAY "OUTPUT: " OUTPUT-STRING.
     DISPLAY " ".

     GOBACK.

 1000-PROC-STR SECTION.
* INITIALIZE VARIABLES.
     MOVE 0 TO SPACE-COUNT.
     MOVE SPACES TO PARTS-WHOLE.
     MOVE SPACES TO OUTPUT-STRING.
* REMOVE LEADING SPACES
     INSPECT PROC-STRING
        TALLYING SPACE-COUNT FOR LEADING SPACES.
     MOVE PROC-STRING (SPACE-COUNT + 1:80) TO PROC-STRING.
* UNSTRING DATA
     UNSTRING PROC-STRING
       DELIMITED BY ALL SPACES
       INTO PARTS-TABLE (1) PARTS-TABLE (2) PARTS-TABLE (3) PARTS-TABLE (4)
            PARTS-TABLE (5) PARTS-TABLE (6) PARTS-TABLE (7) PARTS-TABLE (8)
            PARTS-TABLE (9)
     END-UNSTRING.
* STRING DATA BACK
     STRING PARTS-TABLE (1) DELIMITED BY SPACES SPACE DELIMITED BY SIZE
            PARTS-TABLE (2) DELIMITED BY SPACES SPACE DELIMITED BY SIZE
            PARTS-TABLE (3) DELIMITED BY SPACES SPACE DELIMITED BY SIZE
            PARTS-TABLE (4) DELIMITED BY SPACES SPACE DELIMITED BY SIZE
            PARTS-TABLE (5) DELIMITED BY SPACES SPACE DELIMITED BY SIZE
            PARTS-TABLE (6) DELIMITED BY SPACES SPACE DELIMITED BY SIZE
            PARTS-TABLE (7) DELIMITED BY SPACES SPACE DELIMITED BY SIZE
            PARTS-TABLE (8) DELIMITED BY SPACES SPACE DELIMITED BY SIZE
            PARTS-TABLE (9) DELIMITED BY SPACES SPACE DELIMITED BY SIZE
       INTO OUTPUT-STRING
     END-STRING.

Output is:

CODE

 Input: a/c balace is $200.00      name    is    smith                                  
Output: a/c balace is $200.00 name is smith                                             
 Input:    a/c balace is      $200.00                                                  
Output: a/c balace is $200.00                                                           

Measurement is not management.

RE: Removing spaces form a Message

The output got mangled somewhere between copying and posting, it shouldn't have those additional lines.

Measurement is not management.

RE: Removing spaces form a Message

Hi Glenn9999,
Before I wrote the piece of code I posted above, I tried it first to solve with UNSTRING but I used probably DELIMITED BY SPACE instead of DELIMITED BY ALL SPACES and so I got in end effect what I don't  expected - a space in some table elements.
smile
But the disadvantage with using STRING and UNSTRING is, that you need to know maximal possible number of words in the string.
 

RE: Removing spaces form a Message

anirbanc

this subject has been dealt with numerous times in this forum.  If you do a Search (see tab at top of this message thread, right next to Forum) for UNSTRING you will find many useful threads dealing with this topic.

mikrom

Quote (mikrom):

the disadvantage with using STRING and UNSTRING is, that you need to know maximal possible number of words in the string.

I disagree.  You only need to know the maximum length of any input string you wish to handle.  You can do it with 3 areas (input, temporary holding, output) where the temp and output areas are at least as large as the input field.

CODE

           MOVE SPACES                 TO OUTDATA
           MOVE 1                      TO POS-OUT
           MOVE 1                      TO POS-IN
           PERFORM WITH TEST AFTER
               UNTIL POS-IN  >= LENGTH OF INDATA
               OR    POS-OUT >= LENGTH OF OUTDATA
               OR    TEMP (1:LEN) = SPACES
                   UNSTRING INDATA     DELIMITED BY ALL SPACES
                                                 OR ALL TAB-CHAR
                                                 OR ALL LINE-FEED
                                                 OR ALL FORM-FEED
                       INTO TEMP       DELIMITER IN DLM
                                       COUNT     IN LEN
                                       POINTER   POS-IN
                   END-UNSTRING
                   IF  LEN > ZERO
                       IF  POS-OUT + LEN + 1 >= LENGTH OF OUTDATA
                           PERFORM DISPLAY-OUTDATA
                       END-IF
                       STRING TEMP (1:LEN) DELIMITED BY SIZE
                              DLM          DELIMITED BY SIZE
                         INTO OUTDATA      POINTER POS-OUT
                       END-STRING
                   ELSE
                       MOVE HIGH-VALUES    TO TEMP
                       MOVE 1              TO LEN
                   END-IF
           END-PERFORM
           .
      *
       DISPLAY-OUTDATA.
           ADD  1                          TO LINE-OUT
           DISPLAY OUTDATA                 LINE     LINE-OUT
                                           POSITION COL-OUT
           MOVE SPACES                     TO OUTDATA
           MOVE 1                          TO POS-OUT
           .

Code what you mean,
and mean what you code!
But by all means post your code!

Razalas

RE: Removing spaces form a Message

Hi razalas,

Thanks for the suggestions.
Your code is very interesting, for example I have never seen using OR with DELIMITED before.

But I need to compile and debug your code, so I understand it better - if I only look at it now, it seems to be complicated for me
smile

RE: Removing spaces form a Message

mikrom,

sorry I was/am a bit rushed when I responded earlier so I didn't post the full program. It might be easier to understand if I put the working storage out there too.  I'll try to do tonight after I get home.  I was hoping the procedure division would be enough to shed some light on how to do this if you don't know in advance how many individual words you might have to expect.

Code what you mean,
and mean what you code!
But by all means post your code!

Razalas

RE: Removing spaces form a Message

razalas,

It's not a big problem for me to add the working storage to the procedure division you posted here.
But I don't have the COBOL compiler at my hands now, because here in Europe it's about 22.35 and I'm at home. I only have COBOL compiler at my work, so I can try your example first tomorrow.
smile

But if you want to post the complete example it would be easier.

 

RE: Removing spaces form a Message

I think your making this harder than it is.

Tom

CODE


000010**PROGRAM1      
000020 IDENTIFICATION DIVISION.
000030 PROGRAM-ID. Program1 AS "Debug_Cobol_Applications_General.Program1".
000040 DATA DIVISION.
000050 WORKING-STORAGE SECTION.
000060 01  SUB1                        PIC 999 VALUE 1.
000070 01  SUB2                        PIC 999 VALUE 1.
000080 01  INPUT-DATA.
000090     05 FILLER                   PIC X(100) VALUE
000100         "THIS             IS          A TEST       ".
000110 01  OUTPUT-DATA                 PIC X(100) VALUE SPACES.     
000120
000130 PROCEDURE DIVISION.
000140 START-IT-ALL1.
000150     MOVE INPUT-DATA(SUB1:1) TO OUTPUT-DATA(SUB2:1)                
000160     PERFORM
000170       VARYING SUB1 FROM 2 BY 1
000180          UNTIL SUB1 > 100 OR INPUT-DATA(SUB1:) = SPACES
000190     IF INPUT-DATA(SUB1:1) NOT = SPACES OR OUTPUT-DATA(SUB2:1) NOT = SPACES
000200          ADD 1 TO SUB2
000210          MOVE INPUT-DATA(SUB1:1) TO OUTPUT-DATA(SUB2:1)                
000220      END-IF
000230     END-PERFORM.
000240
000250     DISPLAY "INPUT  :" INPUT-DATA.
000260     DISPLAY "OUTPUT :" OUTPUT-DATA.
000270     STOP RUN.
000280    
000290     
000300 END PROGRAM PROGRAM1.
000310

RE: Removing spaces form a Message

You're quite right, TLeaders.  That is the algorithm I have used over the years.  Of course, back in the old days, we didn't have referance modification available to us, so we had to redefine the strings as arrays of bytes; but the basic algorithm remains the same.

RE: Removing spaces form a Message

webrabbit

I know what you mean. Sometimes you just have to love these new fangeled gadgets.

Tom

RE: Removing spaces form a Message

Quote (mikrom):

But the disadvantage with using STRING and UNSTRING is, that you need to know maximal possible number of words in the string.

Not really.  I learned a little trick as you will see in this and in another thread.

Quote (webrabbit):

Of course, back in the old days, we didn't have referance modification available to us, so we had to redefine the strings as arrays of bytes; but the basic algorithm remains the same.

Of course, the problem is the "new fangled gadgets" are what you have to use to make things efficient in the end.  COBOL is very horrible when it comes to table access and reference modification.  I've had time on programs be cut in half time-wise to go away from this kind of thing to the "new fangled gadgets".  Although, this problem won't show much difference compared to some others.

Not related to what I said, but here's another way to do it:

CODE

 IDENTIFICATION DIVISION.
 PROGRAM-ID. NEWFILE1.
 ENVIRONMENT DIVISION.
 INPUT-OUTPUT SECTION.
 FILE-CONTROL.
     SELECT INFILE ASSIGN TO "INDATA.TXT"
     ORGANIZATION IS LINE SEQUENTIAL.
     SELECT OUTFILE ASSIGN TO "OUTDATA.TXT"
     ORGANIZATION IS LINE SEQUENTIAL.
 DATA DIVISION.
 FILE SECTION.
 FD  INFILE
     Record Varying in Size from 1 to 80
          Depending on WS-Char-Cnt
     BLOCK CONTAINS 0 RECORDS.
 01  INFILE-REC.
     05  Char Occurs 1 to 80 times
        Depending on WS-Char-Cnt.
        10  Each-Char       Pic X.
 FD  OUTFILE
     BLOCK CONTAINS 0 RECORDS.
 01  OUTFILE-REC  PIC X(80).

 WORKING-STORAGE SECTION.
 01  TIMING-PROC.
     04  Start-Time       Pic 99/99/99/99.
     04  End-Time         Pic 99/99/99/99.
 01  PROCESSING-VARIABLES.
     04  WS-CHAR-CNT               PIC 9(4) COMP-5.
     04  PROC-STRING               PIC X(80).
     04  TV1                       PIC X(80).
     04  TV2                       PIC X(80).
     04  PV1                       PIC S9(4) COMP-5.
     04  EOF-DATA                  PIC X VALUE "N".
 01  OUTPUT-VARIABLES.
     04  OUTPUT-STRING             PIC X(80).

 PROCEDURE DIVISION.
 0000-MAIN SECTION.
     Move Function Current-Date (9:8)     To Start-Time.

     OPEN INPUT INFILE
          OUTPUT OUTFILE.
     READ INFILE INTO PROC-STRING
       AT END MOVE "Y" TO EOF-DATA
     END-READ.
     PERFORM UNTIL EOF-DATA = "Y"
       PERFORM 1000-PROC-STR
       WRITE OUTFILE-REC FROM OUTPUT-STRING
       READ INFILE INTO PROC-STRING
         AT END MOVE "Y" TO EOF-DATA
       END-READ
     END-PERFORM.
     CLOSE INFILE OUTFILE.
     Move Function Current-Date (9:8)     To END-Time.
     DISPLAY "END: " END-TIME.
     DISPLAY "START: " START-TIME.
     GOBACK.

 1000-PROC-STR SECTION.
     MOVE 1 TO PV1.
     MOVE SPACES TO OUTPUT-STRING.
     PERFORM UNTIL PV1 > 80
       UNSTRING PROC-STRING DELIMITED BY ALL SPACES INTO TV1
             WITH POINTER PV1
       END-UNSTRING
       MOVE SPACES TO TV2
       STRING OUTPUT-STRING DELIMITED BY SPACES
              "*" DELIMITED BY SIZE
              TV1 DELIMITED BY SPACES
         INTO TV2
       END-STRING
       MOVE TV2 TO OUTPUT-STRING
     END-PERFORM.
     INSPECT OUTPUT-STRING REPLACING ALL "*" BY " ".
* REMOVE LEADING SPACES
     MOVE 0 TO PV1.
     INSPECT OUTPUT-STRING
       TALLYING PV1 FOR LEADING SPACES.
     MOVE OUTPUT-STRING (PV1 + 1:) TO OUTPUT-STRING.

Measurement is not management.

RE: Removing spaces form a Message

Glenn, you say that COBOL is horrible in table access and reference modification.  My experience has been that this is not true, as long a you avoid stupid things like non-binary subscripts and pointers.  Indices help too.  I don's know about pc COBOL as I only know mainframe assembly, so I can't really comment on pc COBOL, but Liant's technical support say there's no problem there either.  Perhaps you could document what you mean by "horrible.".

Your code fails if the input string contains an "*", or whatever other character you might use for a marker.  Furthermore, you have both a String and an Unstring inside a Perform loop.  Both of these statements have very high overhead, much more than referance modification could have.  In addition, there is a great deal of redundant data movement inside the loop.  I watched the data move around and it is very bewildering.

RE: Removing spaces form a Message

Quote:


Perhaps you could document what you mean by "horrible.".

I did in the next sentence.  All table access in any COBOL I've touched is horrible compared to most other languages.  This counts the list that you mentioned, which is the standard dogma that works for COBOL.  COBOL (both mainframe and PC) just doesn't handle tables well.

Let me relate to you another example of mine, which has nothing to do with STRING, UNSTRING and INSPECT, but still has something to do with table access.  I got to playing around in some downtime when I was working with coding different sorts in COBOL and testing their execution time on the mainframe (IBM COBOL for this and that, etc).  

I found something curious, though.  The sorts that, by traditional wisdom are the fastest (like quicksort), were actually quite slow within COBOL.  I found this quite interesting, so I tested the algorithms further by counting different operations, and discovered something.  The fastest algorithm, Combsort (3X faster in fact!), is the one that touches the table the least.  And yes I was using indexes on all things.  And yes, PC COBOL is just as consistent - you would think they would try to use the same algorithmic techniques that are used in the PC compilers where quicksort actually is the fastest.

Quote:


Your code fails if the input string contains an "*", or whatever other character you might use for a marker.

Any byte can be used there without a problem, even non-printable characters which would never appear in a standard text string.  Not a problem with what was posted.

Quote:


Both of these statements have very high overhead, much more than referance modification could have.

Are you judging by what you think is happening by reading the source, or actually learning what's happening behind the scenes?  Have you tested these things to see?   Behind the scenes, STRING UNSTRING and INSPECT do things much more efficiently in most cases than what can be done in COBOL.  

Like I mentioned, this thread involves much simpler things than the case I found where going to those things in a program reduced the execution time by half.  But I did test what was posted in this thread (as copied, no modifications) before I made my assertion on a copy of Fujitsu COBOL 3.0, by throwing a large number of text strings at them.  Want to take a guess which one was faster?  Hint: It wasn't what TLeaders posted.

Measurement is not management.

RE: Removing spaces form a Message

By "other languages" do you mean anything like Visual Basic?  At one job, my boss asked me to see what I could do with a VB program that was taking half the day to run.  I wrote a COBOL program (Micro Focus V3.5) which ran literally in the blink of an eye (it was done before one's finger could be lifted off the Enter key).  Perhaps a C program would be faster.  But then we didn't have a C compiler.

BTW, many languages don't manipulate the strings in a table, they manipulate the string pointers.  In the past, I have written a COBOL program to do it that way, it was much faster.

RE: Removing spaces form a Message

Well Glenn, you got me.  I ran tests with RM/COBOL V11.01 and Micro Focus COBOL V 3.2.46 (very old)  I ran three loops, each 90,000 times 1) your code 2) referance modification and 3) an empty loop.

MF COBOL 19.67 sec, 33.28 sec, .11 sec
RM/COBOL 1.33 sec, 5.26 sec, .02 sec

So there's someting going on behind the scenes.  

I left the mainframe world very shortly after STRING, UNSTRING, and referance modification were introduced, so I never had an oportunity to see how they were implemented there.  Referance modification should have been implemented at a very low level, the addresssing schemae for IBM mainframes has included referance modification as an integral part since the 60s.

Red Flag This Post

Please let us know here why this post is inappropriate. Reasons such as off-topic, duplicates, flames, illegal, vulgar, or students posting their homework.

Red Flag Submitted

Thank you for helping keep Tek-Tips Forums free from inappropriate posts.
The Tek-Tips staff will check this out and take appropriate action.

Reply To This Thread

Posting in the Tek-Tips forums is a member-only feature.

Click Here to join Tek-Tips and talk with other members! Already a Member? Login

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close