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.