Skip to main content

Problem:

Haven't you ever wondered why there is not a simple way of obtaining this, like an intrinsic function, or using INSPECT?

Or maybe you have tried something like:

       working-storage section.    

       77 ws-name                      pic x(50).  

       77 ws-count                     pic 9(03).  

       procedure division.    

       move "Micro Focus" to ws-name  

       inspect ws-name tallying ws-count for characters  

       display ws-count.

and discovered that you were just counting every character as a space is also another character, so return of that INSPECT is the length of the variable, that is 50 instead of the desired 11 that is the length of the "Micro Focus" string.

Resolution:

Inspect ... for characters, takes into account ALL characters, including SPACES. That is why you get the length of the variable as a result.

The following example (also in the attached zip) shows a few ways of doing this.

       program-id. countingcharstest.

       working-storage section.

       77 ws-name                      pic x(50).

       77 ws-count                     pic 9(03) comp-5.

       procedure division.

       move "Micro Focus" to ws-name

      * This version counts all characters in ws-name, including spaces

      * (that is also a character)

       move 0 to ws-count

       inspect ws-name tallying ws-count for characters

       display "all characters: " ws-count

      * This version counts all characters in ws-name, before the first

      * space character is found. That should only count the characters

      * in the word "Micro" and stop there.

       move 0 to ws-count

       inspect ws-name tallying ws-count for characters before space

       display "all characters before space: " ws-count

      * This is the only version using inspect that returns the expected

      * result. It involves reversing ws-name and then counting the

      * leading spaces that would be the number of spaces at the end in

      * the original ws-name, once we know that, we can calculate the

      * result if we know the total length of the variable.

      * This solution is quite costly performance wise, and it is not

      * that simple to use at all.

       move 0 to ws-count

       inspect function reverse (ws-name) tallying ws-count

               for leading spaces

       compute ws-count = length of ws-name - ws-count

       display "string length using reverse inspect: " ws-count

      * SOLUTION using PERFORM (simpler and less costly):

      * This version uses a very simple perform that searches ws-name,

      * starting from the end, for the first character that is different

      * to spaces.

       perform varying ws-count from length of ws-name by -1

               until ws-name (ws-count:1) not= spaces

                     or ws-count = 0

       end-perform

       display "with a very simple perform: " ws-count

      * Finally,

      * if it is needed to apply this quite often to a number of

      * different variables, it may be better for you to write a

      * little routine to perform this function in a generic way

      * that can be called each time it is needed.

        call "stringvaluelength" using by reference ws-name

                                   by value length of ws-name

                                   by reference ws-count

        display "result calling routine: " ws-count

        stop run.

Attachments:

countingchars.zip

Old KB# 6974