36
10 Novembro 2005 Leitura e Escrita de Fi cheiros Processamento d e Texto 1 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 2005Leitura e Escrita de Ficheiros Processamento de Texto 1 Jorge Cruz DI/FCT/UNL Introdução aos Computadores e à Programação 1º Semestre 2005/2006

Embed Size (px)

Citation preview

Page 1: 10 Novembro 2005Leitura e Escrita de Ficheiros Processamento de Texto 1 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

Leitura e Escrita de FicheirosProcessamento de Texto

Jorge CruzDI/FCT/UNL

Introdução aos Computadores e à Programação1º Semestre 2005/2006

Page 2: 10 Novembro 2005Leitura e Escrita de Ficheiros Processamento de Texto 1 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

2

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.

Page 3: 10 Novembro 2005Leitura e Escrita de Ficheiros Processamento de Texto 1 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

3

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.

Page 4: 10 Novembro 2005Leitura e Escrita de Ficheiros Processamento de Texto 1 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

4

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.

Page 5: 10 Novembro 2005Leitura e Escrita de Ficheiros Processamento de Texto 1 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

5

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.

Page 6: 10 Novembro 2005Leitura e Escrita de Ficheiros Processamento de Texto 1 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

6

Exemplo de Leitura e Escrita de Ficheiros18218 16.3920213 11.3512567 10.18

.........

20190 19.9313945 12.33

• Assumamos um ficheiro em duas colunas, em que

– A primeira coluna representa o número de um aluno

– A segunda coluna, a nota que o aluno obteve numa determinada disciplina

• Escrever um ficheiro em 3 colunas em que:

– 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.

18218 16.39 2.39 20213 11.35 -2.65 12567 10.18 -3.82

.............

20190 19.93 5.93 13945 12.33 -1.67

•Calcular a média das notas obtidas pelos alunos Objectivos:

Page 7: 10 Novembro 2005Leitura e Escrita de Ficheiros Processamento de Texto 1 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

7

Entrada de Dados

[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);

• 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.

18218 16.3920213 11.3512567 10.18

.........

20190 19.9313945 12.33

Page 8: 10 Novembro 2005Leitura e Escrita de Ficheiros Processamento de Texto 1 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

8

Entrada de Dados

[num,nota,count] = fscanf(fid,"%i%f",”C”);num = 18218nota = 16.39count = 2

• 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").

18218 16.3920213 11.3512567 10.18

.........

20190 19.9313945 12.33

Page 9: 10 Novembro 2005Leitura e Escrita de Ficheiros Processamento de Texto 1 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

9

Entrada de Dados

[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

• 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).

18218 16.3920213 11.3512567 10.18

.........

20190 19.9313945 12.33

Page 10: 10 Novembro 2005Leitura e Escrita de Ficheiros Processamento de Texto 1 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

10

Entrada de Dados

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;

• A instrução fscanf pode pois ser usada no ciclo abaixo, que instancia os vectores Numeros e Notas.

• Notas:1. A chamada de fscanf é feita antes do ciclo. 2. A condição de entrada no ciclo é !feof3. A variável n guarda o número de alunos lidos.

Page 11: 10 Novembro 2005Leitura e Escrita de Ficheiros Processamento de Texto 1 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

11

Tratamento dos Dados

Media = sum(Notas)/n;

• Uma vez obtidos os vectores Numeros e Notas com n alunos, a média das notas obtidas pode ser calculada:

• 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;

Page 12: 10 Novembro 2005Leitura e Escrita de Ficheiros Processamento de Texto 1 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

12

Saída dos Dados

[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);

• 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”)

Page 13: 10 Novembro 2005Leitura e Escrita de Ficheiros Processamento de Texto 1 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

13

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);

Page 14: 10 Novembro 2005Leitura e Escrita de Ficheiros Processamento de Texto 1 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

14

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”).

Page 15: 10 Novembro 2005Leitura e Escrita de Ficheiros Processamento de Texto 1 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

15

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”)

Page 16: 10 Novembro 2005Leitura e Escrita de Ficheiros Processamento de Texto 1 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

16

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’

Page 17: 10 Novembro 2005Leitura e Escrita de Ficheiros Processamento de Texto 1 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

17

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”) a = [65,66,67] – Cadeias em vectores : 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)

Page 18: 10 Novembro 2005Leitura e Escrita de Ficheiros Processamento de Texto 1 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

18

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.

Page 19: 10 Novembro 2005Leitura e Escrita de Ficheiros Processamento de Texto 1 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

19

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.

Page 20: 10 Novembro 2005Leitura e Escrita de Ficheiros Processamento de Texto 1 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

20

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 ”

Page 21: 10 Novembro 2005Leitura e Escrita de Ficheiros Processamento de Texto 1 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

21

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

Page 22: 10 Novembro 2005Leitura e Escrita de Ficheiros Processamento de Texto 1 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

22

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

Page 23: 10 Novembro 2005Leitura e Escrita de Ficheiros Processamento de Texto 1 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

23

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 my_str_before da seguinte forma

my_str_before (s1,s2) = 1 se s1 << s2 0 se s1 = s2 -1 se s1 >> s2

Page 24: 10 Novembro 2005Leitura e Escrita de Ficheiros Processamento de Texto 1 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

24

Comparação de Cadeias de Caracteres

function t = my_str_tail(s) c = length(s); if c == 1 t =""; else t = substr(s,2,c-1); endif;endfunction;

• 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).

• 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).

Page 25: 10 Novembro 2005Leitura e Escrita de Ficheiros Processamento de Texto 1 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

25

Comparação de Cadeias de Caracteresfunction 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;

Page 26: 10 Novembro 2005Leitura e Escrita de Ficheiros Processamento de Texto 1 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

26

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.

Page 27: 10 Novembro 2005Leitura e Escrita de Ficheiros Processamento de Texto 1 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

27

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.

Page 28: 10 Novembro 2005Leitura e Escrita de Ficheiros Processamento de Texto 1 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

28

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;

Page 29: 10 Novembro 2005Leitura e Escrita de Ficheiros Processamento de Texto 1 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

29

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); endforendfunction;

Page 30: 10 Novembro 2005Leitura e Escrita de Ficheiros Processamento de Texto 1 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

30

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;

Page 31: 10 Novembro 2005Leitura e Escrita de Ficheiros Processamento de Texto 1 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

31

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;

Page 32: 10 Novembro 2005Leitura e Escrita de Ficheiros Processamento de Texto 1 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

32

Comparação de Cadeias com 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;

• 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.

• 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

Page 33: 10 Novembro 2005Leitura e Escrita de Ficheiros Processamento de Texto 1 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

33

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 = “\n Rui \t Lopes”; s2 = “RUI lopes”;

sn1 = toupper(s1), sn2 = toupper(s2), t1 = my_str_norm_before(s1,s2), t2 = my_str_norm_before(sn1,sn2) sn1 = “\n RUI \t LOPES”

sn2 = “RUI LOPES” t1 = -1 t2 = 0

Page 34: 10 Novembro 2005Leitura e Escrita de Ficheiros Processamento de Texto 1 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

34

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.

Page 35: 10 Novembro 2005Leitura e Escrita de Ficheiros Processamento de Texto 1 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

35

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)

Page 36: 10 Novembro 2005Leitura e Escrita de Ficheiros Processamento de Texto 1 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

36

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”