Nós comentamos no subconjunto F90/2, que os computadores poderiam operar com informações alfabéticas, mas que isto seria visto num capítulo mais adiante. Agora vamos aprender a manusear este tipo de dados, pois, até então, só trabalhamos com dados do tipo real ou inteiro.
Neste capítulo veremos como:
1) Ler dados alfanuméricos através de linha (registros) de dados;
2) Mudá-los de um lugar para outro na memória do computador; e
3) Como investigar uma parte desta informação.
O termo informação alfabética, não é adequado para o que iremos aprender e utilizar neste subconjunto. Ele é verdadeiro para informações que contém apenas letras, como por exemplo, o nome de uma pessoa:
“Maria da Silva”
Mas. quando queremos manusear informações envolvendo letras, números, e caracteres especiais, como por exemplo, o endereço de uma pessoa:
“RUA MACIEL PINHELRO, 333”
Então, ele se torna inadequado. Este tipo de informação nós chamaremos de informação alfanumérica. Isto porque o conjunto de caracteres não envolve somente o uso de letras, mas também o uso de números, sinais de pontuação, espaços em branco e outros caracteres especiais, como no caso do texto de um livro, ou como neste exemplo:
“Será que estou sendo claro nesta explicação?”
No conjunto de caracteres acima temos: 44 caracteres, onde:
- 6 são caracteres brancos;
- 1 é o ponto de interrogação; e
- os restantes são letras.
Da mesma maneira que reservamos espaço de memória no computador para variáveis inteiras ou reais, nós reservamos uma parte da memória para armazenarmos nossos dados alfanuméricos. Uma variável de caracteres chamada FRASE pode ser declarada como:
CHARACTER*50 :: FRASE
ou
CHARACTER :: FRASE*50
ou
CHARACTER (LEN = 50) :: FRASE
Nós sabemos que FRASE é uma variável de caracteres por causa da palavra chave Fortran CHARACTER, e que a quantidade memória reservada para esta variável deve conter até 50 caracteres.
Por exemplo, queremos guardar na variável FRASE seguinte conjunto de caracteres:
“Isto é muito simples de se aprender”
Então, esta frase será. colocada a partir da 1a. Posição mais à esquerda da variável. Como este conjunto de caracteres possui 35 caracteres, então, as primeiras 35 posições, serão preenchidas com eles e o restante será preenchido com caracteres branco, ou seja:
1 1 2 3 4 5
1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
Isto é muito simples de se aprender
Agora se o conjunto de caracteres a ser guardado for maior que o tamanho definido para a variável, então o conjunto será truncado a partir da primeira posição excedente do tamanho da variável. Por exemplo, definimos uma variável caractere chamada NOME, com 10 caracteres:
CHARACTER (LEN = 10) :: NOME
Nela, queremos guardar o conjunto de caracteres que possui 15 caracteres:
Aline Guimarães de Faria
Logo, será armazenado na variável apenas:
1
1 2 3 4 5 6 7 8 9 0
Aline Guim
Então, os caracteres restante serão perdidos.
Nós aprendemos a mostrar um conjunto de caracteres no subconjunto F90/1 do Fortran na forma de constante literal tal como:
WRITE (*, *) “VOLUME”
Agora que sabemos como usar variáveis de caracteres, vamos aprender a ler informações alfanuméricas através da entrada padrão e mostrá-las.
Por exemplo, programa que lê e imprime nome de uma pessoa:
PROGRAM mostra_nome
IMPLICIT NONE
! Programa que lê e imprime o nome de uma pessoa
CHARACTER (LEN = 20) ::
nome
WRITE(*, *) “Lê e imprime o nome de uma pessoa:”
WRITE(*, *)
WRITE(*, *) “Digite o nome a ser mostrado:”
WRITE (*, *)
READ (*, *) nome
WRITE(*, *) “Nome lido:”
WRITE(*, *) nome
STOP
END PROGRAM mostra_nome
Se for digitada a cadeia de caracteres: Amanda Nascimento, o resultado apresentado pelo programa será o nome:
Amanda Nascimento
Nós podemos também atribuir diretamente valor a uma variável de caracteres como fazemos com as variáveis reais e inteiras. Por exemplo:
CHARACTER :: NOME*15
NOME = “Amanda Nascimento”
Nós precisamos comparar conjuntos de. caracteres por 2 motivos: um deles é para efeito de reconhecimento, ou seja, para saber se 2 conjuntos de caracteres são o mesmo ou não. A comparação entre conjuntos de caracteres alfanuméricos é feita através de operação lógica, como para dados numéricos. O valor desta operação é:
- VERDADEIRA – Se o conjunto de caracteres forem iguais.
- FALSA – Se o conjunto de caracteres forem diferentes.
Vejamos então um exemplo de programa de reconhecimento que lê e mostra um conjunto de palavras até encontrar a palavra PARE, mostrando, no final, a quantidade de palavras lidas, exceto a palavra PARE:
PROGRAM le_mostra
IMPLICIT NONE
! Programa que lê e imprime palavras até que seja encontrada
! a palavra PARE
CHARACTER (LEN = 10) :: palavra
INTEGER :: contador
WRITE (*, *) “Programa que lê e imprime palavras até que seja&
& encontrada a palavra PARE, mostrando no final a&
& quantidade de palavras lidas:“
WRITE (*, *)
contador = 0
WRITE (*, *) “Informe uma palavra:“
READ (*, *) palavra
DO WHILE (palavra /= “PARE” .AND. palavra /= “Pare” .AND.&
palavra /= “pare”)
WRITE (*, *) palavra
contador = contador + 1
WRITE (*, *) “Informe uma palavra:“
READ (*, *) palavra
END DO
WRITE (*, *) “Quantidade de palavras impressas: “, contador
STOP
END PROGRAM le_mostra
Se a seqüência de dados digitada for:
SALVADOR
ARACAJU
RECIFE
MACEIO
PARE
As palavras mostradas como saída do programa, serão:
SALVADOR
ARACAJU
RECIFE
MACEIO
Note que a última palavra, PARE, nunca será mostrada. Porém, se não existir a palavra PARE como dado, o programa ficará sempre esperando ler uma nova palavra para ser mostrada.
O outro motivo para comparação de conjunto de caracteres é quando queremos colocá-los em ordem.
O alfabeto e os dígitos seguem a seguinte ordem:
- 0 vem antes der 9;
- A vem antes de Z;
- o branco tem menor valor
A ordem de precedência entre os caracteres, que o Fortran manipula, é definido pela tabela ASCII.
Os operadores .GT . e .LT. são usados para comparar os conjuntos de caracteres. Se dois conjuntos de tamanhos diferentes devem ser comparados, são incluídos caracteres, brancos à direita do conjunto menor para que ambos os conjuntos tenham o mesmo comprimento durante a comparação. Por exemplo:
“JOAO” .GT . “JORGE” Þ FALSO
“JOAO .LT. “JOAQUIM” Þ VERDADEIRO
“ A” .LT. “A” Þ VERDADEIRO
“22” .GT. “156” Þ VERDADEIRO
Por exemplo, um programa que lê 10 palavras e mostra aquela que seria a última em ordem alfabética:
PROGRAM
ordem_alfabetica
IMPLICIT NONE
! Lê 10 nomes e mostra a último nome em
ordem alfabética
CHARACTER (LEN = 15) :: nome, ultimo
INTEGER :: vezes
WRITE(*, *) “Lê 10 nomes e mostra o último
nome em&
& ordem alfabética”
WRITE(*, *)
ultimo = “”
WRITE(*, *) “Informe os 10 nomes: ”
DO vezes = 1, 10, 1
READ (*, *) nome
IF (nome .GT. ultimo) THEN
ultimo = nome
END IF
END DO
WRITE(*, *) “A último nome em ordem
alfabética é ”, ultimo
STOP
END PROGRAM
ordem_alfabetica
Se as palavras digitadas forem:
NILCE
VANIA
FATIMA
MARLUCE
LASTENIA
PAULETE
JANAINA
ANA
MONICA
AMANDA
O resultado do programa será:
A última palavra na ordem alfabética é : Vania
Note que a variável ULTIMA foi inicializada com caracteres branco porque ela precisa de um valor inicial para ser usado no comando IF, e este valor deve ser mínimo para que na primeira comparação a variável ULTIMA possa ser substituída pelo primeiro dado lido, no caso, NILCE.
Porque a condição (“NILCE” .GT. “ ”) é VERDADEIRA.
Nós podemos concatenar (juntar ou unir) duas cadeias de caracteres, criando uma terceira. Para isso utilizamos o operador de concatenação (//).
Por exemplo, se quisermos unir o conteúdo da variável caractere estado com a constante “ é um estado do Brasil”, armazenando a nova cadeia na variável nova_cadeia, poderemos ter:
CHARACTER (LEN = 10) :: estado
CHARACTER (LEN = 35) :: nova_cadeia
estado = “Pernambuco”
nova_cadeia = estado // “ é um estado do Brasil”
WRITE(*, *) “<”, nova_cadeia, “>”
O resultado da impressão seria:
<Pernambuco é um estado do Brasil >
Numa expressão de concatenação, pode-se concatenar várias constantes e/ou variáveis do tipo caractere.
Nós podemos extrair ou incluir uma parte ou sub-cadeia numa uma cadeia de caracteres. Utilizando a seguinte estrutura sintática:
<cadeia original>(<posição de início>:<posição final>)
Considerando que as posições dos caracteres de uma cadeia são numeradas a partir de 1 da esquerda para a direita, <posição de início> é a posição do caractere da cadeia original, onde começa a sub-cadeia e, <posição final> é a posição do caractere da cadeia original, onde termina a sub-cadeia. A cadeia de onde se extrairá sub-cadeia pode ser uma constante ou uma variável.
Por exemplo, se quisermos extrair e mostrar a palavra “estado” da cadeia “Pernambuco é um estado do Brasil”, podemos fazer:
WRITE(*, *) “Pernambuco é um estado do Brasil”(17:22)
Ou
CARACTERE (LEN=32) :: cadeia
...
cadeia = “Pernambuco é um estado do Brasil”
WRITE(*, *) cadeia(17:22)
Se omitirmos a <posição de início>, a posição de inicio será considerada a primeira posição da cadeia original e, se omitirmos a <posição final>, a posição final será considerada a última posição da cadeia original.
Assim, cadeia(:10) extrai “Pernambuco” e cadeia(24:) extrai “do Brasil”.
Podemos também fazer atribuições a uma sub-cadeia de uma cadeia, utilizando o recurso mostrado acima no lado esquerdo de uma atribuição, resultando assim em alteração de parte da cadeia original:
cadeia(16:22) = “a parte”
WRITE(*, *) cadeia
O resultado da impressão seria: “Pernambuco é uma parte do Brasil”
Fortran fornece uma série de funções para manipulação de cadeias de caracteres, como mostra o quadro a seguir:
Função |
Descrição |
ACHAR(i) |
Retorna o caractere de posição i na tabela ASCII. |
ADJUSTL(cadeia) |
Alinha a cadeia à esquerda, retirando os brancos do início e colocando-os no final. |
ADJUSTR(cadeia) |
Alinha a cadeia à direita, retirando os brancos do final e colocando-os no início. |
CHAR(i, tipo) |
Retorna o i-ésimo caractere no conjunto de caracteres especificado por tipo. Se omitir o tipo o conjunto será o ASCII. |
IACHAR(c) |
Posição do caractere c na tabela ASCII. |
INDEX(cadeia, sub-cadeia, back) |
Se back é falso (back=.false.) ou não está presente, retorna a posição da primeira ocorrência da sub-cadeia na cadeia. Se back é verdadeiro (back=.true.), retorna a última ocorrência da sub-cadeia na cadeia. Zero é retornado, se não houver nenhuma ocorrência. |
LEN(cadeia) |
Retorna o tamanho de cadeia. |
LEN_TRIM(cadeia) |
Retorna o tamanho de cadeia, excluídos os brancos à direita. |
REPEAT(cadeia, n) |
Cria uma nova cadeia com n repetições de cadeia. |
SCAN(cadeia, conjunto, back) |
Procura na cadeia por qualquer um dos caracteres do conjunto. |
TRIM(cadeia) |
Retorna uma nova cadeia sem os brancos da direita. |
VERIFY(cadeia, conjunto, back) |
Verifica se um conjunto de caracteres contém todos os caracteres da cadeia. |
Um programa para encontrar o tamanho de uma cadeia, excluídos seus brancos à direita. Este programa implementa o mesmo que a função LEN_TRIM():
PROGRAM tamanho
IMPLICIT NONE
CHARACTER (LEN = 30) :: cadeia
INTEGER :: fim
WRITE (*, *) "Informe a cadeia a ser medida: "
READ (*, *) cadeia
fim = 30
DO WHILE (fim > 0 .AND. cadeia(fim:fim) == " ")
fim = fim - 1
END DO
WRITE (*, *) "Tamanho da cadeia = ", fim
STOP
END PROGRAM tamanho
Se quisermos inverter os caracteres de uma mesma cadeia, poderemos usar este programa:
PROGRAM inverte1
IMPLICIT NONE
CHARACTER (LEN = 40) :: cadeia
CHARACTER (LEN=1) :: caractere
INTEGER :: p
WRITE (*, *) "Informe a cadeia a ser invertida: "
READ (*, *) cadeia
DO p = 1, 20, 1
caractere = cadeia(p:p)
cadeia(p:p) = cadeia(41-p:41-p)
cadeia(41-p:41-p) = caractere
END DO
WRITE (*, *) "Cadeia invertida -->", cadeia
STOP
END PROGRAM inverte1
Uma segunda versão do programa anterior para gerar uma segunda cadeia a partir da inversão dos caracteres de uma cadeia original:
PROGRAM inverte2
IMPLICIT NONE
CHARACTER (LEN = 40) :: cadeia1, cadeia2
INTEGER :: p
WRITE (*, *) "Informe a cadeia a ser invertida: "
READ (*, *) cadeia1
DO p = 1, 40, 1
cadeia2(p:p) = cadeia1(41-p:L41-p)
END DO
WRITE (*, *) "Cadeia invertida -->", cadeia2
STOP
END PROGRAM inverte2
A seguir um programa completo Fortran para abreviar um nome de pessoa. Por exemplo, se o programa ler o nome “Andréa Guimarães de Faria” como entrada gera como saída: Faria, A. G.
PROGRAM abrevia_nome
IMPLICIT NONE
CHARACTER (LEN = 30) :: nome, abreviatura
INTEGER :: isub, fsub, inome, fnome
WRITE (*, *) "Informe o nome a abreviar: "
READ (*, *) nome
fsub = 30
DO WHILE (fsub > 0 .AND. nome(fsub:fsub) == " ")
fsub = fsub - 1
END DO
isub = fsub
DO WHILE (isub > 0 .AND. nome(isub:isub) /= " ")
isub = isub - 1
END DO
abreviatura = nome(isub+1:fsub)//","
inome = 1
DO WHILE(inome < isub)
fnome = inome
DO WHILE (fnome < isub .AND. nome(fnome:fnome) /= " ")
fnome = fnome + 1
END DO
IF (nome(inome:fnome-1) /= "de") THEN
abreviatura = abreviatura(:LEN_TRIM(abreviatura))//&
&" "//nome(inome:inome)//"."
END IF
inome = fnome
DO WHILE (inome < isub .AND. nome(inome:inome) == " ")
inome = inome + 1
END DO
END DO
WRITE (*, *) "Nome abreviado--> ", abreviatura
STOP
END PROGRAM abrevia_nome
1) Dizer se são verdadeiras ou falsas, as comparações dos seguintes conjuntos de caracteres:
a) “LUIS HENRIQUE” .EQ . “LUIZ HENRIQUE ”
b) “CASA 23” .GT. “CASA 222”
c) “ICC” .LT. “I C C”
d) “RUA DA AURORA 1070” .LT. “RUA DA AURORA
1070”
e) “SIMONE”
.GE. “MIRIAN”
2) Escrever um programa que leia uma lista de 10 nomes tal como a segue, e mostre uma lista com todas as pessoas chamada Faria.
Faria, R. M.
Nicolletti, P. S.
Barbosa, A.
Faria, A. G.
Medeiros, O.
Faria. E. F.
Faria, Z. M. M.
Falcão, N. S.
Faria, F. A. M.
Farias, J.
3) Fazer um programa que leia 10 títulos de filmes com censura e imprima aqueles com censura livre.
Exemplo:
“A BELA ADORMECIDA” “'LIVRE”
“CASANOVA” “18”
“E O VENTO LEVOU” “LIVRE”
etc.