Leitura e Escrita de Ficheiros
Processamento de Texto
Jorge Cruz
DI/FCT/UNL
Introdução aos Computadores e à Programação
1º Semestre 2005/2006
10 Novembro 2005
Leitura e Escrita de Ficheiros
Processamento de Texto
1
Armazenamento de Dados
• Quando a quantidade de dados é grande, não é razoável ou
mesmo possível introduzi-los “manualmente” num programa.
• Tipicamente esses dados são armazenados em ficheiros que
têm de ser lidos pelos programas que os tratam.
• As funções básicas de manutenção de ficheiros (criação,
alteração e destruição, localização, acesso ao seu conteúdo,
etc.) são definidas no sistema de ficheiros (file system) ,
componente do sistema operativo (Operating System Windows, Linux, MacOS, ...).
• Todas as linguagens de programação têm acesso a essas
funções básicas (primitivas), implementadas através de
chamadas ao sistema, mas que são disponibilizadas ao nível
da linguagem através de instruções próprias.
10 Novembro 2005
Leitura e Escrita de Ficheiros
Processamento de Texto
2
Armazenamento de Dados
• Existe uma grande variedade de formas nessas instruções mas
algumas características são razoavelmente gerais:
– Antes de se escrever ou ler num ficheiro, este tem de ser aberto num
modo apropriado (leitura, escrita, leitura/escrita,...).
– Na abertura de um ficheiro, este é associado a um “canal” com um
identificador (tipicamente um número) único. Todos os acessos ao
ficheiro referem esse valor e não o nome com que o ficheiro é
conhecido no sistema de ficheiros.
– Os acessos de leitura e escrita de dados dos ficheiros dependem da
forma como os dados são codificados. Estes podem ser armazenados
como texto ou numa forma codificada que optimiza o espaço.
– Após todos os acessos pretendidos terem sido executados, o ficheiro
deve ser fechado.
• Como estas operações podem ser muito variadas, vamos
centrar-nos nos acessos a ficheiros texto em OCTAVE.
10 Novembro 2005
Leitura e Escrita de Ficheiros
Processamento de Texto
3
Entrada de Dados
• Após a abertura de um ficheiro texto, ele pode ser lido de
duas formas básicas:
– Leitura carácter a carácter, sendo tarefa do programador interpretar as
sequências de caracteres como números, palavras, etc...
– Leitura de acordo com determinados padrões (templates) em que
existem primitivas da linguagem que interpretam directamente os
caracteres para o tipo de dados pretendido.
• Por exemplo, assumamos que um ficheiro tem a sequência de
caracteres “ 23   45.2 ”. Neste caso podemos
– ler os 11 caracteres e tendo em atenção os espaços interpretar esses
caracteres como dois números (um inteiro e outro decimal).
– Indicar como padrão de leitura um inteiro seguido de um decimal que
são retornados em variáveis indicadas.
10 Novembro 2005
Leitura e Escrita de Ficheiros
Processamento de Texto
4
Saída de Dados
• O armazenamento de dados num ficheiro segue passos
semelhantes. A abertura de um ficheiro em modo escrita, cria
um ficheiro, que pode ser escrito de duas formas básicas:
– Escrita carácter a carácter, sendo tarefa do programador criar as
sequências adequadas de caracteres para representar números,
palavras, etc...
– Escrita de acordo com determinados padrões (templates)
disponibilizados por primitivas da linguagem.
• Por exemplo, para se escreverem os dados 23 e 45.2 num
ficheiro ( “ 23   45.2 ”), pode-se
– escrever os 11 caracteres sequencialmente, isto é,
‘ ’,‘ ’,‘2’,’3’,‘ ’,‘ ’,‘4’,‘5’,‘.’,’2’,‘ ’
– indicar como padrão de escrita um inteiro (com 4 dígitos, seguido de
um espaço, seguido de um decimal com 5 casas, incluindo uma casa
decimal, seguido de um espaço.
10 Novembro 2005
Leitura e Escrita de Ficheiros
Processamento de Texto
5
Exemplo de Leitura e Escrita de Ficheiros
• Assumamos um
colunas, em que
ficheiro
em
duas
– A primeira coluna representa o número de
um aluno
– A segunda coluna, a nota que o aluno
obteve numa determinada disciplina
18218
20213
12567
.........
20190
13945
Objectivos:
• Calcular a média das notas obtidas pelos alunos
• Escrever um ficheiro em 3 colunas em
18218
que:
20213
– As duas primeiras colunas são como antes
– A 3ª coluna, representa a diferença entre a
nota obtida pelo aluno e a média das
notas.
10 Novembro 2005
Leitura e Escrita de Ficheiros
Processamento de Texto
16.39
11.35
10.18
12567
19.93
12.33
16.39
2.39
11.35
10.18
-2.65
-3.82
.............
20190
13945
19.93
12.33
5.93
-1.67
6
Entrada de Dados
• A instrução fopen abre o ficheiro com o nome “notas.txt”, em
modo de leitura (“r” - read), e atribui-lhe um número de canal
‘fid’, usado posteriormente.
• A instrução fclose fecha o canal com número ‘fid.
[fid,msg] = fopen("notas.txt", "r");
i = 0; Numeros = []; Notas = [];
[num,nota,count] = fscanf(fid,"%i%f",”C”);
while !feof(fid)
i = i + 1;
Numeros(i) = num;
Notas(i) = nota;
[num,nota,count] = fscanf(fid,"%i%f",”C”);
endwhile;
n=i;
fclose(fid);
10 Novembro 2005
Leitura e Escrita de Ficheiros
Processamento de Texto
18218
20213
12567
16.39
11.35
10.18
.........
20190
13945
19.93
12.33
7
Entrada de Dados
• A instrução [num,nota,count] = fscanf(fid,"%i%f",”C”)
permite ler dados
–
–
–
–
–
do canal de entrada (1º argumento - fid)
de acordo com um padrão (template - ,"%i%f")
como na linguagem C (3º argumento – “C”)
os dados efectivamente lidos são colocados nas variáveis num e nota
o seu número é colocado na variável count.
• Neste caso, são lidos 2 números do canal de entrada. O primeiro
é um inteiro ("%i") e o segundo é decimal ("%f").
[num,nota,count] = fscanf(fid,"%i%f",”C”);
num = 18218
nota = 16.39
count = 2
18218
20213
12567
.........
20190
13945
10 Novembro 2005
Leitura e Escrita de Ficheiros
Processamento de Texto
16.39
11.35
10.18
19.93
12.33
8
Entrada de Dados
• Quando não há mais dados para ler, a instrução
[num,nota,count] = fscanf(fid,"%i%f",”C”)
retorna num e nota vazios (num = nota = []) e count = 0.
• Normalmente existe uma função “end of file” para indicar se
a última leitura já foi feita após o fim do ficheiro. Em Octave
essa função é expressa por feof(fid).
[num,nota,count] = fscanf(fid,"%i%f",”C”)
F = feof(fid).
count = 2, num = 13945, nota = 12.33, F = 0
[num,nota,count] = fscanf(fid,"%i%f",2)
F = feof(fid).
count = 0, num = [], nota = [],
F = 1
10 Novembro 2005
Leitura e Escrita de Ficheiros
Processamento de Texto
18218
20213
12567
16.39
11.35
10.18
.........
20190
13945
19.93
12.33
9
Entrada de Dados
• A instrução fscanf pode pois ser usada no ciclo abaixo, que
instancia os vectores Numeros e Notas.
i = 0; Numeros = []; Notas = [];
[num,nota,count] = fscanf(fid,"%i%f",”C”);
while !feof(fid)
i = i + 1;
Numeros(i) = num;
Notas(i) = nota;
[num,nota,count] = fscanf(fid,"%i%f",”C”);
endwhile;
n = i;
• Notas:
1. A chamada de fscanf é feita antes do ciclo.
2. A condição de entrada no ciclo é !feof
3. A variável n guarda o número de alunos lidos.
10 Novembro 2005
Leitura e Escrita de Ficheiros
Processamento de Texto
10
Tratamento dos Dados
• Uma vez obtidos os vectores Numeros e Notas com n alunos, a
média das notas obtidas pode ser calculada:
Media = sum(Notas)/n;
• Um vector D pode ser definido com a diferença entre a nota
obtida por cada aluno e a média de todas as notas:
D = zeros(1,n);
for i = 1:n
D(i) = Notas(i) - Media;
endfor;
10 Novembro 2005
Leitura e Escrita de Ficheiros
Processamento de Texto
11
Saída dos Dados
• As instruções fopen e fclose são semelhantes, mas com modo de
escrita (“w” - write).
• A instrução fprintf escreve no canal de saída com identificador
fid os 3 valores indicados com formatos:
– Inteiro com 5 dígitos (1º dado – Numero(i))
– Decimal, com 7 casas, das quais duas decimais (2º/3º dado – Notas(i) e D(i))
– Separados por espaços (no template) e com mudança de linha (“\n”)
[fid,msg] = fopen("notas_out.txt", "w");
for i = 1:n
fprintf(fid,"%5i %7.2f %7.2f\n", Numeros(i),Notas(i),D(i));
endfor;
fclose(fid);
10 Novembro 2005
Leitura e Escrita de Ficheiros
Processamento de Texto
12
Programa Octave
[fid,msg] = fopen("notas.txt", "r");
i = 0; Numeros = []; Notas = [];
[num,nota,count] = fscanf(fid,"%i%f",”C”);
while !feof(fid)
i = i + 1;
Numeros(i) = num;
Notas(i) = nota;
[num,nota,count] = fscanf(fid,"%i%f",”C”);
endwhile;
n=i;
fclose(fid);
Media = sum(Notas)/n;
D = zeros(1,n);
for i = 1:n
D(i) = Notas(i) - Media;
endfor;
[fid,msg] = fopen("notas_out.txt", "w");
for i = 1:n
fprintf(fid,"%5i %7.2f %7.2f\n", Numeros(i),Notas(i),D(i));
endfor;
fclose(fid);
10 Novembro 2005
Leitura e Escrita de Ficheiros
Processamento de Texto
13
Processamento de Texto
• Muita informação útil, nomeadamente em tarefas de gestão,
não é do tipo numérico.
• Por exemplo, variadas entidades (pessoas, empresas,
disciplinas, departamentos, etc...) têm associado um nome
que se pode querer processar (por exemplo ordenar).
• Este é apenas um exemplo de situações em que se pretende
que os programas efectuem processamento de texto.
• Todas as linguagens de programação prevêem pois tipos de
dados para este fim, nomeadamente
– Caracteres;
– Cadeias de caracteres (“strings”).
10 Novembro 2005
Leitura e Escrita de Ficheiros
Processamento de Texto
14
Caracteres
• Os caracteres mais utilizados (representados no código
ASCII - American Standard Code for Information Interchange) incluem:
• Letras (52), maiúsculas (26) e minúsculas (26)
• Dígitos (10)
• Espaço e outros caracteres “visíveis” (34)
– ‘“()[]{},.:;=<>+-*\|/^~´`#$%&_!?@
• Caracteres de controle (32)
– horizontal tab (\t), new line (\n), alert (\a), ...
• Outros caracteres, (ç, ã, ñ, š , ø , ∞,  , Σ, ш, ‫ך‬, ‫ﭏ‬, ‫ )غغ‬só
podem ser representados em códigos mais avançados e não
são “suportados” em algumas linguagens de programação
(em Octave, uma variável não pode ter o nome “acção”)
10 Novembro 2005
Leitura e Escrita de Ficheiros
Processamento de Texto
15
Cadeias de Caracteres
• Cadeias de caracteres são sequências (ordenadas) de
caracteres.
• Em quase todas as linguagens, dados do tipo caracteres e
cadeia (incluindo simples caracteres) são representados entre
delimitadores, que podem ser aspas (“ ”) ou plicas (‘ ’).
• Devem sempre abrir-se e fechar-se com o mesmo tipo de
delimitadores.
• Quando se pretende incluir um dos delimitadores no texto,
podem usar-se sequências de escape
– nome = ‘ Maria Martins d\’Albuquerque’
• ou usar-se o outro delimitador
– nome = “ Maria Martins d’Albuquerque”
– frase = ‘Ele exclamou: “Óptimo” e fugiu’
10 Novembro 2005
Leitura e Escrita de Ficheiros
Processamento de Texto
16
Cadeias de Caracteres e Vectores
• Em geral, e Octave não foge à regra, cadeias de caracteres são
“implementadas” como vectores dos códigos dos caracteres.
• Muitas funções e operações em Octave exigem a utilização do
tipo correcto. Duas funções permitem transformar
– Vectores em cadeias : toascii: <cadeia>  <vector>
>> a = toascii(“ABC”)
– Cadeias em vectores :
 a = [65,66,67]
setstr: <vector>  <cadeia>
>> b = setstr([97,98,99])
 b = ‘abc’
• O Octave não é muito estrito no que se refere aos tipos de dados.
Por exemplo, permite operações “numéricas” com cadeias,
fazendo a conversão de tipos necessária
>> c = ‘abc’* 1
 c = [97,98,99]
• Nota: Estas “facilidades” tornam difícil a detecção de erros de programação e
não devem ser usadas (ou apenas com muito cuidado)
10 Novembro 2005
Leitura e Escrita de Ficheiros
Processamento de Texto
17
Conversão de Cadeias de Caracteres
• Cadeias de caracteres podem ser processados de várias formas.
Para as mais comuns, existem funções predefinidas.
• Algumas dessas funções permitem converter cadeias de
caracteres que representam números para os próprios números.
• Exemplo: Dada a cadeia “ 23.76 ” (com espaços), a sua
conversão para um número é obtida com a função str2num.
>> s = “ 23.76 “; a = str2num(s); b = 2*a
 b = 47.52
• É interessante comparar o resultado acima com (porquê???)
>> s = “ 23.76 “; b = 2*s
 b = [64,100,102,92,110,108,64,64]
• A conversão oposta, pode fazer-se com a função num2str.
10 Novembro 2005
Leitura e Escrita de Ficheiros
Processamento de Texto
18
Concatenação de Cadeias de Caracteres
• As cadeias podem ser concatenadas. Esta operação é utilizada
para juntar numa só cadeia a informação que está dispersa por
várias cadeias. Por exemplo, para juntar
– O(s) nome(s) próprio(s) ao(s) apelido(s)
– Os vários campos de um endereço (rua, nº, andar, local, etc.)
• O Octave tem uma função strcat, para esse efeito.
• Exemplo: Juntar um nome próprio e um apelido.
>> np = “Rui”; ap = “Lopes”; nome= strcat(np,“ ”,ap)
 nome = “Rui Lopes”
• De notar a utilização da cadeia com um branco (“ ”) para espaçar
o nome próprio e o apelido.
10 Novembro 2005
Leitura e Escrita de Ficheiros
Processamento de Texto
19
Partição de Cadeias de Caracteres
• As cadeias podem ser “partidas” noutras mais simples. Neste
caso pode haver várias formas de fazer a partição. Uma possível
é através de caracteres que funcionam como separadores
(tipicamente espaços).
• O Octave tem uma função, split, para esse efeito, criando uma
matriz de cadeias, cada cadeia na sua linha, com brancos
acrescentados se necessário
• Exemplo: Separar os nomes (próprios e apelidos) de uma pessoa.
>> nome = “Rui da Costa Pina”; nms = split(nome,“ ”)
 nms = “Rui ”
“da
”
“Costa”
“Pina ”
10 Novembro 2005
Leitura e Escrita de Ficheiros
Processamento de Texto
20
Extracção de Cadeias de Caracteres
• Por vezes estamos interessados apenas em partes de uma cadeia.
Uma forma comum de o fazer é indicar
– o índice do primeiro caracter pretendido para a subcadeia; e
– o comprimento da subcadeia.
• O Octave tem uma função, substr, para esse efeito. Por
exemplo: Separar os nomes (próprios e apelidos) de uma pessoa.
>> nome = “Rui da Costa Pina”;
nm1 = substr(nome,1,3), nm2 = substr(nome,5,2),
nm3 = substr(nome,8,5), nm4 = substr(nome,14,4),
 nm1= “Rui”, nm2= “da”, nm3= “Costa”, nm4= “Pina”
• Os índices variam de 1 ao comprimento da cadeia. Este
comprimento é obtido pela função length.
>> nome = “Rui da Costa Pina”; x = length(nome)
 x= 17
10 Novembro 2005
Leitura e Escrita de Ficheiros
Processamento de Texto
21
Comparação de Caracteres
• Uma operação vulgar no processamento de texto é a ordenação
“por ordem alfabética”.
• Esta ordenação requer a comparação “alfabética” de caracteres.
• Esta pode ser feita através da comparação “numérica” dos
códigos dos caracteres.
• A comparação só é fácil se os códigos usados respeitam a ordem
alfabética, o que acontece em todos os códigos. Por exemplo em
ASCII, o código dos caracteres “A” e “B” é, respectivamente, 65
e 66, pelo que se pode fazer a correspondência pretendida
o caracter c1 “vem antes do” caracter c2  c1 < c2
• Exemplo: >> teste = “a” < “b”
 teste = 1
10 Novembro 2005
Leitura e Escrita de Ficheiros
Processamento de Texto
22
Comparação de Cadeias de Caracteres
• A comparação “literal” pode ser obtida a partir da comparação
caracter a caracter.
• O Octave tem uma função, strcmp, para verificar se duas
cadeias são idênticas.
>> nm1 = “Rui Costa”; nm2 = “Rui Costa”; t = strcmp(nm1,nm2)
 t = 1
• Para o teste de precedência alfabética (designado por “<<“) o
Octave não dispõe de funções predefinidas. Mas elas podem ser
definidas tendo em conta a comparação caracter a caracter.
• Vamos pois definir uma função
forma
1
my_str_before (s1,s2) =
0
-1
10 Novembro 2005
my_str_before da seguinte
se s1 << s2
se s1 = s2
se s1 >> s2
Leitura e Escrita de Ficheiros
Processamento de Texto
23
Comparação de Cadeias de Caracteres
• Dada a natureza recursiva da função my_str_before, esta utiliza
uma função auxiliar, my_str_tail, para obter a “cauda da cadeia
(isto é, sem o seu primeiro caracter).
function t = my_str_tail(s)
c = length(s);
if c == 1 t ="";
else
t = substr(s,2,c-1);
endif;
endfunction;
• A função my_str_before compara os primeiros caracteres das
cadeias (se existirem). Se estes forem iguais, compara as caudas
das cadeias (chamada recursiva).
10 Novembro 2005
Leitura e Escrita de Ficheiros
Processamento de Texto
24
Comparação de Cadeias de Caracteres
function b = my_str_before(s1,s2)
c1 = length(s1); c2 = length(s2);
if
c1 == 0 & c2 == 0
b = 0;
elseif c1 == 0 & c2 > 0
b = 1;
elseif c1 > 0 & c2 == 0
b = -1;
else
% c1 > 0 & c2 > 0
if
s1(1) < s2(1)
b = 1;
elseif s1(1) > s2(1)
b = -1;
else
t1 = my_str_tail(s1);
t2 = my_str_tail(s2);
b = my_str_before(t1,t2);
endif;
endif;
endfunction;
10 Novembro 2005
Leitura e Escrita de Ficheiros
Processamento de Texto
25
Comparação de Cadeias de Caracteres
• A comparação de cadeias de caracteres “interpretáveis” (por
exemplo, de texto em português) é mais complexa.
• Os problemas mais frequentes são de 3 tipos:
– Ocorrência de espaços (e outros caracteres brancos)
• “Rui Santos” = “ Rui Santos “ ???
– Tratamento de letras maiúsculas e minúsculas
• “Rui Santos” = “RUI SANTOS “ ???
– Caracteres especiais (com acentos e cedilhas)
• “João França” = “Joao Franca“ ???
• Estes problemas têm de ser considerados no contexto apropriado
(Franca e França são apelidos diferentes, ou o terminal
(telemóvel) não tinha o caracter “ç” ?), e requerem algoritmos
dedicados.
10 Novembro 2005
Leitura e Escrita de Ficheiros
Processamento de Texto
26
Comparação de Cadeias com Brancos
• Os caracteres brancos servem para separar os “significativos”.
Os mais vulgares são os espaços, mas existem outros para
mudança de linha (“\n”, “\r” ou “\f”), ou tabulação (“\t” e “\v”).
• No código ASCII todos têm códigos inferiores a 32 (espaço).
• A comparação de cadeias pode simplificar-se se a comparação
for feita após normalização. Esta normalização, consiste em
– eliminar todos os brancos prefixos/sufixos, i.e. antes/depois
do primeiro/último caracter significativo.
– Substituir todos os separadores (grupos de brancos, tabs,
mudanças de linha, etc. por um só branco).
• Algumas funções predefinidas podem auxiliar na normalização,
mas o Octave não tem esta função predefinida.
10 Novembro 2005
Leitura e Escrita de Ficheiros
Processamento de Texto
27
Substituição de Brancos por Espaços
• Assumindo que todos os caracteres brancos têm código inferior a
32, podemos utilizar a função my_str_remctr, indicada abaixo,
para substituir todos os caracteres brancos por espaços.
function t = my_str_remctr(s)
for i = 1:length(s)
if toascii(s(i)) < 32
t(i) = " ";
else
t(i) = s(i);
endif;
endfor;
endfunction;
10 Novembro 2005
Leitura e Escrita de Ficheiros
Processamento de Texto
28
Eliminação de Brancos Prefixos e Sufixos
• O Octave dispõe de uma função (deblank) que elimina todos os
espaços sufixos.
• A eliminação dos brancos prefixos pode igualmente usar essa
função se se inverter (passá-la de trás para a frente) a cadeia.
Essa inversão pode usar a função my_str_rev, indicada abaixo
function r = my_str_rev(s)
c = length(s);
for i = 1:c
r(i) = s(c-i+1);
endfor
endfunction;
10 Novembro 2005
Leitura e Escrita de Ficheiros
Processamento de Texto
29
Eliminação de Espaços Repetidos
• A eliminação dos espaços repetidos pode ser feita usando a
função my_str_remrep, indicada abaixo. A função percorre toda
a cadeia mantendo a informação (na variável booleana
ultimo_branco) sobre se o último caracter era branco. Nesse
caso, se o caracter for espaço não o copia (seria repetido).
function t = my_str_remrep(s)
j = 1; ultimo_branco = 0;
for i = 1:length(s)
if s(i) != " "
t(j) = s(i); j = j+1; ultimo_branco = 0;
elseif !ultimo_branco
t(j) = s(i); j = j+1; ultimo_branco = 1;
endif;
endfor;
endfunction;
10 Novembro 2005
Leitura e Escrita de Ficheiros
Processamento de Texto
30
Normalização de Cadeias de Caracteres
• A normalização de cadeias de caracteres pode ser feita usando a
função my_str_norm, indicada abaixo, que utiliza todas as
funções anteriores, da forma esperada.
• Primeiro, substitui os brancos por espaços. Depois elimina os
espaços sufixos. Em terceiro lugar elimina os brancos prefixos
(eliminando os brancos sufixos da cadeia invertida, invertendo
de novo o resultado). Finalmente, os espaços repetidos são
removidos.
function sn = my_str_norm(s)
s1 = my_str_remctr(s)
s2 = deblank(s1);
s3 = my_str_rev(deblank(my_str_rev(s2)));
sn = my_str_remrep(s3);
endfunction;
10 Novembro 2005
Leitura e Escrita de Ficheiros
Processamento de Texto
31
Comparação de Cadeias com Brancos
• A comparação de cadeias de caracteres pode ser feita usando a
função my_str_norm_before, indicada abaixo, que não
considera os caracteres brancos.
function b = my_str_norm_before(s1,s2)
sn1 = my_str_norm(s1);
sn2 = my_str_norm(s2);
b = my_str_before(sn1,sn2);
endfunction;
• As diferenças podem ser exemplificadas em baixo.
>> t = my_str_before(“Rui
Lopes”, “ Rui Lopes”)
 t = -1
>> t = my_str_norm_before(“Rui
Lopes”, “ Rui Lopes”)
 t = 0
10 Novembro 2005
Leitura e Escrita de Ficheiros
Processamento de Texto
32
Comparação com Maiúsculas/Minúsculas
• A comparação de cadeias de caracteres pode ser igualmente
prejudicada pela existência de letras maiúsculas e minúsculas.
• O Octave tem algumas funções que facilitam o tratamento deste
tipo de situações, nomeadamente as funções tolower e toupper,
que convertem os caracteres maiúsculos / minúsculos em
caracteres minúsculos / maiúsculos.
>> s1
sn1
t1
t2
=
=
=
=
“\n Rui \t Lopes”; s2 = “RUI lopes”;
toupper(s1), sn2 = toupper(s2),
my_str_norm_before(s1,s2),
my_str_norm_before(sn1,sn2)
 sn1
sn2
t1
t2
10 Novembro 2005
=
=
=
=
“\n RUI \t LOPES”
“RUI LOPES”
-1
0
Leitura e Escrita de Ficheiros
Processamento de Texto
33
Conversão entre Maiúsculas/Minúsculas
• As funções anteriores assumem um código ASCII, em que os
caracteres brancos têm códigos abaixo de 32.
• Nesse código ASCII, a conversão entre maiúsculas e minúsculas
pode ser feita adicionando ou subtraindo a sua diferença aos
códigos respectivos. Esta diferença é 32, como pode ser
verificado em
>> dif = toascii(“A”) – toascii(“a”)
 dif = -32
• No entanto, a utilização destes valores pode ser problemática, se
forem usados outros códigos. É da responsabilidade da
implementação da linguagem interpretar ter em atenção os
códigos usados (que podem não ser ASCII) e disponibilizar
primitivas independentes desses códigos.
10 Novembro 2005
Leitura e Escrita de Ficheiros
Processamento de Texto
34
Conversão independente do Código
• Algumas dessas primitivas são
– isalpha(s) 1 se s for alfabético (maiúscula ou minúscula)
– islower(s) 1 se s for uma minúscula
– isupper(s) 1 se s for uma maiúscula
– isdigit(s)
1 se s for um dígito
– isalnum(s) 1 se s for dígito ou alfabético
– ispucnt
1 se s for um caracter de pontuação
– iscntrl(s)
1 se s for caracter de controle
• Desta forma as funções poderão ser rectificadas para se tornarem
independentes do código usado para representação dos
caracteres. Em particular, o teste
toascii(s(i)) < 32
pode/deve ser substituido por
iscntrl(s2)
10 Novembro 2005
Leitura e Escrita de Ficheiros
Processamento de Texto
35
Cadeias com Caracteres Especiais
• Os caracteres com cedilhas e acentos, típicos do português, não
fazem parte do código ASCII básico, e os seus códigos em
ASCII estendido não respeitam a ordem “natural”.
• Por exemplo, como os códigos dos caracteres “a”, “s” e “ã” são,
respectivamente 97, 115 e 227, o nome João está alfabeticamente
após José, ao contrário do que acontece com Joao.
• Uma forma de manter a ordenação pretendida é utilizar, para
efeitos de ordenação, as cadeias com os caracteres acentuados
substituídos pelos caracteres não acentuados.
• O Octave dispõe de uma função (strrep) que substitui numa
cadeia base, todas as de uma (sub)cadeia por outra.
>> s1 = “João”; s2 = strrep(s1,”ã”,”a”)
 s2 = “Joao”
10 Novembro 2005
Leitura e Escrita de Ficheiros
Processamento de Texto
36
Download

Leitura e Escrita de Ficheiros, Processamento de Texto