Words (1): Uma função para contar a quantidade de palavras numa string
Em outras linguagens, como Java ou Javascript, é possível fazer um split e transformar uma string num array em que cada ocorrência corresponda a uma palavra da string original.
Num primeiro momento, podemos imaginar que o COBOL faria a mesma coisa com o comando UNSTRING, mas existe uma diferença essencial: enquanto Java, Javascript e outras linguagens trabalham com arrays dinâmicos (arrays cuja quantidade de ocorrências se pode definir em tempo de execução), no COBOL temos que estabelecer uma quantidade máxima de palavras para que o UNSTRING funcione do jeito que queremos. Algo como:
UNSTRING UMA-STRING-QUALQUER
DELIMITED BY ALL SPACES
INTO PALAVRA(1)
PALAVRA(2)
PALAVRA(3)
PALAVRA(4)
Se no comando acima, UMA-STRING-QUALQUER tivesse cinco palavras, a quinta seria perdida. Em um programa real…
identification division.
program-id. gtc034.
data division.
working-storage section.
01 uma-string-qualquer pic x(080)
value "perform paragrafo varying indice from 1 by 1".
01 palavra pic x(010) occurs 4.
procedure division.
unstring uma-string-qualquer
delimited by all spaces
into palavra(1)
palavra(2)
palavra(3)
palavra(4)
display "palavra(1)=" palavra(1)
display "palavra(2)=" palavra(2)
display "palavra(3)=" palavra(3)
display "palavra(4)=" palavra(4)
stop run.
…o resultado da execução seria:
> Executing task in folder coblab: gtc034 < palavra(1)=perform palavra(2)=paragrafo palavra(3)=varying palavra(4)=indice
Felizmente usando alguns recursos do COBOL 2002 é possível criar funções que contornam essa limitação. E esses recursos estão disponíveis na maior parte dos compiladores atuais.
Este artigo faz parte de uma série de três onde pretendo mostrar como criei essas funções.
Criando a função getWordCount
A função abaixo foi codificada e testada no GnuCOBOL 3.1.0, mas com poucas alterações pode ser implementada em quase todos os compiladores que incorporaram os recursos do COBOL 2002:
identification division.
function-id. getWordCount.
environment division.
configuration section.
repository.
function all intrinsic.
data division.
working-storage section.
01 subscript binary-short unsigned value zeros.
01 stringState pic 9(001) value zeros.
88 wasSpace value 1 false 0.
linkage section.
01 fullString pic x any length.
01 wordsCounted binary-short unsigned.
procedure division using fullString returning wordsCounted.
0-main.
move zeros to subscript
move zeros to stringState
move zeros to wordsCounted
perform varying subscript from 1 by 1 until subscript > length(fullString)
if fullString(subscript:1) = spaces
set wasSpace to true
else
if subscript = 1
add 1 to wordsCounted
else
if wasSpace
add 1 to wordsCounted
set wasSpace to false
end-if
end-if
end-if
end-perform
goback.
end function getWordCount.
Criando a variável fullString na linkage section com pic x any length a função poderá receber strings de qualquer tamanho. Quem vai definir esse tamanho é o programa chamador.
Outro ponto importante é que essa versão mais recente do GnuCOBOL não permite ainda declarar a cláusula “is initial” no parágrafo function-id da identification division. Por isso, coloquei os três comandos “move zero” no início da procedure, garantindo que as variáveis serão sempre inicializadas se o programa chamador executar a função mais de uma vez.
Testando a função
Codificando um programa chamador…
identification division.
program-id. gtc035.
environment division.
configuration section.
repository.
function getWordCount.
data division.
working-storage section.
01 uma-string-qualquer pic x(080)
value "perform paragrafo varying indice from 1 by 1".
procedure division.
inicio.
display "O conteudo da string possui "
getWordCount(uma-string-qualquer)
" palavras"
stop run.
…temos o seguinte resultado:
> Executing task in folder coblab: gtc035 < O conteudo da string possui 00008 palavras
No próximo artigo…
…vamos mostrar uma função que também em COBOL que usa essa getWordCount para recuperar uma palavra dentro da string.