30
Registos em Ficheiros - Estruturas Pedro Barahona DI/FCT/UNL Introdução aos Computadores e à Programação 2º Semestre 2008/2009 15 Maio 2009 1 Registos em Ficheiros - Estruturas

Registos em Ficheiros - Estruturas Pedro Barahona DI/FCT/UNL Introdução aos Computadores e à Programação 2º Semestre 2008/2009 15 Maio 20091Registos em

Embed Size (px)

Citation preview

Page 1: Registos em Ficheiros - Estruturas Pedro Barahona DI/FCT/UNL Introdução aos Computadores e à Programação 2º Semestre 2008/2009 15 Maio 20091Registos em

Registos em Ficheiros - Estruturas

Pedro BarahonaDI/FCT/UNL

Introdução aos Computadores e à Programação2º Semestre 2008/2009

15 Maio 2009 1Registos em Ficheiros - Estruturas

Page 2: Registos em Ficheiros - Estruturas Pedro Barahona DI/FCT/UNL Introdução aos Computadores e à Programação 2º Semestre 2008/2009 15 Maio 20091Registos em

15 Maio 2009 Registos em Ficheiros - Estruturas 2

Registos em Ficheiros

• Muita informação alfanumérica está registada em ficheiros, na forma de

“registos”. Por exemplo, numa base de dados da empresa, são mantidos ficheiros

com informação sobre os empregados da empresa.

• Muitas aplicações (de gestão) consistem em ler ficheiros e criar outros com a

informação devidamente processada. Por exemplo: ler um ficheiro de empregados

e escrever outro, apenas com os empregados com vencimento superior a 1000 €.

cod nome vencimento data

610 Paul o Fer nandes Lopes 2341. 36 15/ 04/ 1996825 Pedr o Vi ei r a 989. 24 25/ 06/ 1999316 Mar t a Cost a Mar t i ns 1389. 17 05/ 01/ 199234 Rui Vasco Per ei r a 5310. 32 15/ 04/ 1996

723 J or ge Bar at a 767. 26 03/ 09/ 2002

Page 3: Registos em Ficheiros - Estruturas Pedro Barahona DI/FCT/UNL Introdução aos Computadores e à Programação 2º Semestre 2008/2009 15 Maio 20091Registos em

15 Maio 2009 Registos em Ficheiros - Estruturas 3

Registos em Ficheiros

• A primeira questão a resolver consiste no tratamento dos espaços em sequências

de caracteres. Isto porque há duas formas típicas de armazenamento dessas

sequências:

– Comprimento Fixo: As sequências têm sempre o mesmo número de

caracteres (sendo usados espaços se necessário);

– Comprimento Variável: As sequências têm o número de caracteres

necessários, sendo necessários caracteres separadores, tipicamente tabs

(horizontais).

cod nome vencimento data

610 Paul o Fer nandes Lopes 2341. 36 15/ 04/ 1996825 Pedr o Vi ei r a 989. 24 25/ 06/ 1999316 Mar t a Cost a Mar t i ns 1389. 17 05/ 01/ 199234 Rui Vasco Per ei r a 5310. 32 15/ 04/ 1996723 J or ge Bar at a 767. 26 03/ 09/ 2002

Page 4: Registos em Ficheiros - Estruturas Pedro Barahona DI/FCT/UNL Introdução aos Computadores e à Programação 2º Semestre 2008/2009 15 Maio 20091Registos em

15 Maio 2009 Registos em Ficheiros - Estruturas 4

Registos em Ficheiros

• Por exemplo, o nome “Pedro Vieira”, no ficheiro abaixo, pode ser codificado

– Comprimento Fixo: Com 5+1+6 = 12 caracteres (incluindo o espaço), mais

13 espaços, para permitir sequências de comprimento 25, que podem

armazenar nomes com até 25 caracteres (incluindo espaços);

– Comprimento Variável: Apenas com os 12 caracteres necessários, sendo

separado do vencimento por um tab horizontal (‘\t’).

cod nome vencimento data

610 Paul o Fer nandes Lopes 2341. 36 15/ 04/ 1996825 Pedr o Vi ei r a 989. 24 25/ 06/ 1999316 Mar t a Cost a Mar t i ns 1389. 17 05/ 01/ 199234 Rui Vasco Per ei r a 5310. 32 15/ 04/ 1996723 J or ge Bar at a 767. 26 03/ 09/ 2002

Page 5: Registos em Ficheiros - Estruturas Pedro Barahona DI/FCT/UNL Introdução aos Computadores e à Programação 2º Semestre 2008/2009 15 Maio 20091Registos em

15 Maio 2009 Registos em Ficheiros - Estruturas 5

Registos em Ficheiros

• Em Octave (e em C) os dois tipos de codificação requerem instruções de leitura

padronizada (com templates) diferentes.

– Comprimento Fixo: Utiliza-se um template “%nc” em que n é o número de

caracteres a ler;

– Comprimento Variável: Utiliza-se um template “%s”;

• Neste último caso, levanta-se um problema: O template ‘%s’, não lê espaços nem

caracteres brancos. Assim, o nome “Pedro Vieira” seria lido não como 1, mas sim

como 2 sequências. Em geral, ter-se-ia de conhecer o número de nomes (próprios,

apelidos e partículas de ligação).

• Isto pode ser evitado com o uso de espaços especiais (“non break spaces” -

ASCII 160), que são considerados como quaisquer outros caracteres, mas

impressos como espaços.

Page 6: Registos em Ficheiros - Estruturas Pedro Barahona DI/FCT/UNL Introdução aos Computadores e à Programação 2º Semestre 2008/2009 15 Maio 20091Registos em

15 Maio 2009 Registos em Ficheiros - Estruturas 6

Leitura de Ficheiros

• Caso seja necessário, pode converter-se um ficheiro noutro, convertendo-se todos

os espaços em espaços especiais, com a função abaixo:

function x = rem_sp(f_in_name, f_out_name); [f_in, msg] = fopen(f_in_name , "r"); [f_aux,msg] = fopen(f_out_name, "w"); [ch, count] = fscanf(f_in,"%1c","C"); while !feof(f_in) if ch == " " ch = setstr(160); endif; fprintf(f_aux, "%1c", ch); [ch, count] = fscanf(f_in,"%1c","C"); endwhile; fclose(f_in); fclose(f_aux); endfunction;

Page 7: Registos em Ficheiros - Estruturas Pedro Barahona DI/FCT/UNL Introdução aos Computadores e à Programação 2º Semestre 2008/2009 15 Maio 20091Registos em

15 Maio 2009 Registos em Ficheiros - Estruturas 7

• Comprimento Variável:

– Uma vez eliminados os espaços, quer o nome quer a data podem ser lidos com

o template “%s” da instrução fscanf, podendo o registo de um empregado ser

lido quer na forma :

quer numa só instrução

Leitura de Ficheiros

610 Paulo Fernandes Lopes 2341.36 15/04/1996

[cod, count] = fscanf(fid,"%i","C"); [nome, count] = fscanf(fid,"%s","C");[venc, count] = fscanf(fid,"%f","C");[data,count] = fscanf(fid,"%s","C");

[cod,nome,venc,data,count] = fscanf(fid,"%i%s%f%s","C");

Page 8: Registos em Ficheiros - Estruturas Pedro Barahona DI/FCT/UNL Introdução aos Computadores e à Programação 2º Semestre 2008/2009 15 Maio 20091Registos em

15 Maio 2009 Registos em Ficheiros - Estruturas 8

• Comprimento Fixo:

– Cada linha do ficheiro, assumindo-se que um nome é guardado com 25

caracteres, pode ser lida com as seguintes instruções de leitura padronizada,

fscanf

ou numa só instrução

Leitura de Ficheiros

610 Paulo Fernandes Lopes 2341.36 15/04/1996

[cod, count] = fscanf(fid,"%i","C"); [nome, count] = fscanf(fid,"%25c","C");[venc, count] = fscanf(fid,"%f","C");[data,count] = fscanf(fid,"%s","C");

[cod,nome,venc,data,count]=fscanf(fid,"%i%25c%f%s","C");

Page 9: Registos em Ficheiros - Estruturas Pedro Barahona DI/FCT/UNL Introdução aos Computadores e à Programação 2º Semestre 2008/2009 15 Maio 20091Registos em

15 Maio 2009 Registos em Ficheiros - Estruturas 9

• Comprimento Variável:

– Em muitos casos não é possível / desejável trocar espaços por non-break spaces

(por exemplo, devido às dimensões do ficheiro).

– Neste caso pode utilizar-se a insrução fgetl/1 (que permite ler linha a linha um

ficheiro de caracteres) e processar cada registo individualmente.

– A separação dos vários campos pode fazer-se pela instrução split, usando-se o

caracter tab (‘\t’) para separador daq linha em várias linhas da matriz resultante.

– No entanto é necessário ter em conta que ao contrário das instruções fscanf (que

ao lerem dados de qualquer tipo (inteiro, decimal ou string) não atingem o fim do

ficheiro) a instrução fgetl/1 atinge o fim do ficheiro (isto é, torna verdadeira a flag

feof(fid) ) na última linha com valores significativos.

– Assim para podermos escrever códigos semelhantes para todos os tipos de

formatos, iremos definir uma função, ler_linha/1 que conta os dados lidos na

variável count (igualmente existente nas instruções fscanf) e testaremos o fim dos

ficheiros pelo valor dessa variável.

Leitura de Ficheiros - Alternativa

Page 10: Registos em Ficheiros - Estruturas Pedro Barahona DI/FCT/UNL Introdução aos Computadores e à Programação 2º Semestre 2008/2009 15 Maio 20091Registos em

15 Maio 2009 Registos em Ficheiros - Estruturas 10

– Com os pressupostos atrás definidos a função ler_linha/1 pode ser definida como:

– De notar a atribuição inicial de valores a todos os campos para evitar avisos de valores da função não atribuídos (se a leitura da linha for feita após se detectar o fim do ficheiro).

Leitura de Ficheiros - Alternativa

function [cod,nome,venc,data,count] = ler_linha(fid); cod = nome = venc = data = count = false; if !feof(fid) linha = fgetl(fid); Ls = split(linha,"\t"); cod = str2num(Ls(1,:)); nome = deblank(Ls(2,:)); venc = str2num(Ls(3,:)); data = deblank(Ls(4,:)); count = 4; endif;endfunction;

Page 11: Registos em Ficheiros - Estruturas Pedro Barahona DI/FCT/UNL Introdução aos Computadores e à Programação 2º Semestre 2008/2009 15 Maio 20091Registos em

15 Maio 2009 Registos em Ficheiros - Estruturas 11

• Comprimento variável:

– Neste caso o registo de um empregado pode ser escrito como

ou numa só instrução, como anteriormente. Notar agora que

1. Após cada campo, deve ser escrito o tab (‘\t’) de separação, excepto no último

campo, após o que se escreve o caracter (‘\n’)

2. Alguns templates podem ser fixos, (por exemplo, "%7.2f\t”) para evitar as

convenções por omissão do Octave.

Escrita de Ficheiros

fprintf(fid, "%i\t", cod);fprintf(fid, "%s\t", nome);fprintf(fid, "%7.2f\t", venc);fprintf(fid, "%s\n", data);

610 Paulo Fernandes Lopes 2341.36 15/04/1996

Page 12: Registos em Ficheiros - Estruturas Pedro Barahona DI/FCT/UNL Introdução aos Computadores e à Programação 2º Semestre 2008/2009 15 Maio 20091Registos em

15 Maio 2009 Registos em Ficheiros - Estruturas 12

• Comprimento fixo:

– A escrita de ficheiros depende igualmente do formato utilizado para as strings.

Em comprimento fixo, o registo pode ser escrito como

ou numa só instrução, como anteriormente. Notar ainda que

1. O sinal – (em %-25s) justifica, à esquerda, o campo nome.

2. Após o último campo deve ser escrito um caracter (‘\n’), para mudança de linha

Escrita de Ficheiros

fprintf(fid, "%3i", cod); fprintf(fid, "%-25s", nome); fprintf(fid, "%7.2f", venc); fprintf(fid, "%10s", data);

fprintf(fid, "%c", “\n”);

610Paulo Fernandes Lopes 2341.3615/04/1996

Page 13: Registos em Ficheiros - Estruturas Pedro Barahona DI/FCT/UNL Introdução aos Computadores e à Programação 2º Semestre 2008/2009 15 Maio 20091Registos em

15 Maio 2009 Registos em Ficheiros - Estruturas 13

• Podemos agora abordar o problema inicialmente colocado:

1. Ler um ficheiro de empregados; e

2. Escrever outro, apenas com os empregados com vencimento superior a

1000 euros.

• Naturalmente o programa dependerá de os ficheiros serem lidos e escritos em

formato fixo ou variável.

• Assumiremos que esta diferença apenas se reflectirá no campo “nome”, já que o

campo “data” não contem espaços e pode ser lido em formato cadeia (“%s”) sem

problema.

Selecção de Registos

Page 14: Registos em Ficheiros - Estruturas Pedro Barahona DI/FCT/UNL Introdução aos Computadores e à Programação 2º Semestre 2008/2009 15 Maio 20091Registos em

15 Maio 2009 Registos em Ficheiros - Estruturas 14

• Eis a versão para formato fixo :

Selecção de Registos

[f_in, msg_in ] = fopen("empresa_in_fix.txt", "r"); [f_out, msg_out] = fopen("empresa_out_fix.txt", "w");

[cod,nome, venc, data, count] = fscanf(f_in,"%i%25c%f%s","C"); while count > 0 if venc > 1000 fprintf(f_out, "%i%-25s%7.2f\t%10s \n",cod,nome,venc,data); printf( "%-25s%7.2f\t%10s \n", nome,venc,data); endif; [cod,nome, venc, data, count] = fscanf(f_in,"%i%25c%f%s","C"); endwhile;

fclose(f_in); fclose(f_out);

Page 15: Registos em Ficheiros - Estruturas Pedro Barahona DI/FCT/UNL Introdução aos Computadores e à Programação 2º Semestre 2008/2009 15 Maio 20091Registos em

15 Maio 2009 Registos em Ficheiros - Estruturas 15

• A versão para formato variável (com substituição de espaços) :

Selecção de Registos

rem_sp("empresa_in_var.txt", "empresa_in_aux.txt");

[f_aux, msg] = fopen("empresa_in_aux.txt", "r"); [f_out, msg] = fopen("empresa_out_var.txt", "w"); [cod,nome, venc, data, count] = fscanf(f_aux,"%i%s%f%s","C");

while count > 0 if venc > 1000 fprintf(f_out, "%i\t%s\t%7.2f\t%s\n", cod,nome,venc,data); printf( "%s\t%i\t%7.2f\t%s\n", nome,cod,venc,data); endif; [cod,nome, venc, data, count] = fscanf(f_aux,"%i%s%f%s","C"); endwhile;

fclose(f_aux); fclose(f_out);

Page 16: Registos em Ficheiros - Estruturas Pedro Barahona DI/FCT/UNL Introdução aos Computadores e à Programação 2º Semestre 2008/2009 15 Maio 20091Registos em

15 Maio 2009 Registos em Ficheiros - Estruturas 16

• e a versão para formato variável (com leitura de linhas) :

Selecção de Registos

[f_in, msg] = fopen("empresa_in_var.txt", "r"); [f_out, msg] = fopen("empresa_out_lin.txt", "w"); [cod,nome, venc, data,count] = ler_linha(f_in);

while count > 0 if venc > 1000 fprintf(f_out,"%i\t%s\t%7.2f\t%s\n", cod,nome,venc,data); printf( "%s\t%i\t%7.2f\t%s\n", nome,cod,venc,data); endif; [cod,nome, venc, data,count] = ler_linha(f_in); endwhile;

fclose(f_in); fclose(f_out);

Page 17: Registos em Ficheiros - Estruturas Pedro Barahona DI/FCT/UNL Introdução aos Computadores e à Programação 2º Semestre 2008/2009 15 Maio 20091Registos em

15 Maio 2009 Registos em Ficheiros - Estruturas 17

• Podemos agora considerar outro tipo de processamento de informação, que não

envolve necessariamente a escrita de novos ficheiros, correspondente a:

– Cálculo de totais e médias (de vencimentos, por exemplo)

– Determinação de máximos e mínimos (de vencimentos, ou antiguidades)

• Vamos ilustrar estes problemas com programas para determinação dos

vencimentos totais e médios dos empregados da empresa, bem como da

determinação do empregado mais antigo.

• Para ambos os problemas, apenas são apresentadas as versões para formato

variável.

• De notar ainda a instrução printf, que permite escrever no terminal mensagens

formatadas (com os formatos usados em ficheiros).

Processamento de Registos

Page 18: Registos em Ficheiros - Estruturas Pedro Barahona DI/FCT/UNL Introdução aos Computadores e à Programação 2º Semestre 2008/2009 15 Maio 20091Registos em

15 Maio 2009 Registos em Ficheiros - Estruturas 18

• O tratamento de vencimentos utiliza um contador (variável i) de registos lidos e uma

variável (total) para determinação do total dos vencimentos (sendo a média igual à

razão entre total e i).

Processamento de Registos

[f_in, msg] = fopen("empresa_in_var.txt", "r");

i = 0; total = 0;

[cod,nome,venc,data,count] = ler_linha(f_in);

while count> 0 i = i+1; total = total +venc; [cod,nome, venc, data,count] = ler_linha(f_in);endwhile;

fclose(f_in);

printf("\n")printf("o total dos vencimentos é de %7.2f \n", total);printf("a média dos vencimentos é de %6.2f \n", total/i);

Page 19: Registos em Ficheiros - Estruturas Pedro Barahona DI/FCT/UNL Introdução aos Computadores e à Programação 2º Semestre 2008/2009 15 Maio 20091Registos em

15 Maio 2009 Registos em Ficheiros - Estruturas 19

• O tratamento de datas, implica reconhecer quando uma data é anterior a outra, o que é feito com a

função “data_comp” que compara duas datas, sendo armazenada a data menor.

• Como é normal na procura de um mínimo, a data inicial começa por ser uma data maior que todas as

possíveis (no caso do ano 2500!)

Processamento de Registos

[f_in, msg] = fopen("empresa_in_var.txt", "r");

data_menor = "01/01/2500"; [cod,nome,venc,data,read] = ler_linha(f_in); while read if data_comp(data,data_menor) == -1 data_menor = data; antigo = nome; endif; [cod,nome,venc,data,read] = ler_linha(f_in); endwhile;

fclose(f_in);

printf("o empregado mais antigo é %s \n", antigo); printf("com data de entrada %s \n", data_menor);

Page 20: Registos em Ficheiros - Estruturas Pedro Barahona DI/FCT/UNL Introdução aos Computadores e à Programação 2º Semestre 2008/2009 15 Maio 20091Registos em

15 Maio 2009 Registos em Ficheiros - Estruturas 20

• A comparação de datas é feita através da comparação dos anos, meses e dias, das

duas datas

• Naturalmente, há que ter o cuidado de converter inicialmente as cadeias de

caracteres em números (com a função str2num).

Comparação de Datas

function d = data_comp(data1,data2);% data no formato dd/mm/aaaa

ano1 = str2num(substr(data1,7,4)); ano2 = str2num(substr(data2,7,4)); mes1 = str2num(substr(data1,4,2)); mes2 = str2num(substr(data2,4,2)); dia1 = str2num(substr(data1,1,2)); dia2 = str2num(substr(data2,1,2)); d = d_comp(ano1, mes1, dia1, ano2, mes2, dia2);endfunction

Page 21: Registos em Ficheiros - Estruturas Pedro Barahona DI/FCT/UNL Introdução aos Computadores e à Programação 2º Semestre 2008/2009 15 Maio 20091Registos em

15 Maio 2009 Registos em Ficheiros - Estruturas 21

• Uma vez obtidos os anos, dias e meses as datas podem ser comparadas,

comparando-se sucessivamente os anos, e se necessário os meses e dias).

Comparação de Datas

function d = d_comp(ano1, mes1, dia1, ano2, mes2, dia2); if ano1 < ano2 d = -1; elseif ano1 > ano2 d = 1; elseif mes1 < mes2 d = -1; elseif mes1 > mes2 d = 1; elseif dia1 < dia2 d = -1; elseif dia1 > dia2 d = 1; else d = 0; endifendfunction

Page 22: Registos em Ficheiros - Estruturas Pedro Barahona DI/FCT/UNL Introdução aos Computadores e à Programação 2º Semestre 2008/2009 15 Maio 20091Registos em

15 Maio 2009 Registos em Ficheiros - Estruturas 22

• No caso do empregado mais antigo, é interessante informar não só quando ele

entrou ao serviço (isto é , a data), mas também que é ele (isto é, o seu nome) .

• Isto pode fazer-se guardando não só a data de entrada do empregado mais antigo

como também o seu nome

Processamento de Registos

[f_in, msg] = fopen("empresa_in_var.txt", "r");

data_menor = "01/01/2500"; [cod,nome,venc,data,read] = ler_linha(f_in); while read if data_comp(data,data_menor) == -1 data_menor = data; antigo = nome; endif; [cod,nome,venc,data,read] = ler_linha(f_in); endwhile;

fclose(f_in);

printf("o empregado mais antigo é %s \n", antigo); printf("com data de entrada %s \n", data_menor);

Page 23: Registos em Ficheiros - Estruturas Pedro Barahona DI/FCT/UNL Introdução aos Computadores e à Programação 2º Semestre 2008/2009 15 Maio 20091Registos em

15 Maio 2009 Registos em Ficheiros - Estruturas 23

• Todos estes programas obrigam, cada vez que se pretende responder a uma

questão :

1. A ler registos de um ficheiro;

2. A processar cada um dios registos, isoladamente; e, eventualmente

3. A escrever os registos num outro ficheiro

• No entanto, a leitura e escrita de ficheiros, mesmo em “discos rápidos” é

tipicamente milhares de vezes mais lenta que a leitura a partir de dados em

memória.

• Haverá pois vantagem em copiar um ficheiro de registos para memória e passar a

responder às questões a partir de aí.

• Veremos como responder a esta questão em geral e, no caso do Octave, como tal

poderá ser feitos com estruturas e listas.

Estruturas e Listas

Page 24: Registos em Ficheiros - Estruturas Pedro Barahona DI/FCT/UNL Introdução aos Computadores e à Programação 2º Semestre 2008/2009 15 Maio 20091Registos em

15 Maio 2009 Registos em Ficheiros - Estruturas 24

• Embora Vectores e Matrizes sejam muito úteis quando os dados são todos do

mesmo tipo (no Octave, de qualquer tipo numérico), em muitos casos, a informação

que se pretende agrupar com um só identificador não é do mesmo tipo, como é o

caso dos registos considerados anteriormente.

• Por exemplo, um empregado duma empresa pode ser associado à seguinte

informação

– Um código (um número?)

– Um nome (uma cadeia de caracteres)

– Um vencimento (um decimal)

– Uma data de entrada (uma cadeia, ou 3 campos numéricos, para o dia, mês

e ano)

Estruturas

cod nome venc data610 Paulo Fernandes Lopes 2341.36 15/04/1996

Page 25: Registos em Ficheiros - Estruturas Pedro Barahona DI/FCT/UNL Introdução aos Computadores e à Programação 2º Semestre 2008/2009 15 Maio 20091Registos em

15 Maio 2009 Registos em Ficheiros - Estruturas 25

• As várias linguagens de programação permitem o agrupamento destes dados

heterogéneos, com um mesmo identificador de uma forma variada (records no

Pascal, Struct em C, ...)

• O Octave adopta uma designação semelhante à do C, denominando estes

agrupamentos como estruturas.

• Consideremos pois o caso do empregado abaixo, em que gostaríamos de agregar

toda a informação numa única variável, do tipo estrutura, que denotaremos como

emp.

Estruturas

cod nome venc data610 Paulo Fernandes Lopes 2341.36 15/04/1996

Page 26: Registos em Ficheiros - Estruturas Pedro Barahona DI/FCT/UNL Introdução aos Computadores e à Programação 2º Semestre 2008/2009 15 Maio 20091Registos em

15 Maio 2009 Registos em Ficheiros - Estruturas 26

• Uma vez definidos os nomes dos campos da estrutura, podemos atribuir-lhe os

valores pretendidos.

• O acesso a um campo da estrutura é feito fazendo suceder ao nome da estrutura o

nome do campo pretendido, separado por um ponto (‘.’).

• Por exemplo, a atribuição dos 4 valores dos campos pode ser feita pelas seguintes

atribuições:

Estruturas

cod nome venc data610 Paulo Fernandes Lopes 2341.36 15/04/1996

emp.cod = 610;emp.nome = “Paulo Fernandes Lopes”;emp.venc = 2341.36;emp.data=“15/04/1996”;

emp =

Page 27: Registos em Ficheiros - Estruturas Pedro Barahona DI/FCT/UNL Introdução aos Computadores e à Programação 2º Semestre 2008/2009 15 Maio 20091Registos em

15 Maio 2009 Registos em Ficheiros - Estruturas 27

• Uma vez agrupados os vários items de informação numa só variável do tipo

estrutura, podemos referir alguns campos depois de verificar outros.

• Por exemplo, dados vários empregados com o tipo referido, indicar qual o nome dos

que ganham mais de 1000 euros.

• Na sintaxe do Octave, tal poderia ser feito através da instrução condicional

• No entanto este tipo de processamento só é verdadeiramente útil se tivermos a

possibilidade de aceder a todos os empregados de uma forma genérica.

Estruturas

if emp.venc > 1000 then disp(emp.nome)endif

Page 28: Registos em Ficheiros - Estruturas Pedro Barahona DI/FCT/UNL Introdução aos Computadores e à Programação 2º Semestre 2008/2009 15 Maio 20091Registos em

15 Maio 2009 Registos em Ficheiros - Estruturas 28

• Por exemplo, se tivessemos uma tabela com várias linhas, com códigos na primeira

coluna e vencimentos na 2ª coluna, poderíamos apresentar os códigos dos

empregados com vencimento superior a 1000 euros através da seguinte instrução

iterativa:

Por analogia, o que é necessário é poder aceder a uma sequência de (1 a n)

estruturas do tipo da do empregado.

• Na maioria das linguagens de programação, essa analogia é imediata, já que se

podem especificar vectores de estruturas. Tal é o caso do Octave, mas apenas a

partir da versão 3.X (as anteriores usavam o conceito de lista, entretanto

descontinuado).

Tabelas

for i = 1:n if tabela(i,2) > 1000

disp(tabela(i,1)) endif endfor;

1 2

1 610 2341.362 825 989.243 316 1389.174 34 5310.325 723 767.26... ... ...

Page 29: Registos em Ficheiros - Estruturas Pedro Barahona DI/FCT/UNL Introdução aos Computadores e à Programação 2º Semestre 2008/2009 15 Maio 20091Registos em

15 Maio 2009 Registos em Ficheiros - Estruturas 29

• Nestas linguagens, podemos representar o conjunto de empregados através de um

vector, emps, em que cada elemento é uma estrutura (de empregado) com os

campos definidos como anteriormente.

• Agora, para obter os códigos dos empregados com vencimento superior a 1000 euros

bastará usar uma seguinte instrução iterativa, análoga à anterior

Vectores de Estruturas

for i = 1:n if emps(i).vencimento > 1000

disp(emps(i).nome) endif endfor;

i nd cod nome venci ment o dat a1 610 Paul o Fer nandes Lopes 2341. 36 15/ 04/ 19962 825 Pedr o Vi ei r a 989. 24 25/ 06/ 19993 316 Mar t a Cost a Mar t i ns 1389. 17 05/ 01/ 19924 34 Rui Vasco Per ei r a 5310. 32 15/ 04/ 19965 723 J or ge Bar at a 767. 26 03/ 09/ 2002

for i = 1:n if tabela(i,2) > 1000

disp(tabela(i,1)) endif endfor;

Page 30: Registos em Ficheiros - Estruturas Pedro Barahona DI/FCT/UNL Introdução aos Computadores e à Programação 2º Semestre 2008/2009 15 Maio 20091Registos em

15 Maio 2009 Registos em Ficheiros - Estruturas 30

• Podemos agora adaptar os programas anteriores para lerem um vector de

empregados e posteriormente fazerem o seu processamento. A leitura do vector de

empregados pode ser feita pela seguinte função:

Leitura de Vectores de Estruturas

function Emps = ler_emps(filename); [f_in, msg] = fopen(filename, "r"); i = 0; [e.cod, e.nome, e.venc, e.data, count] = ler_linha(f_in); while count> 0 i = i+1; Emps(i) = e; [e.cod, e.nome, e.venc, e.data, count] = ler_linha(f_in); endwhile; fclose(f_in);endfunction;

i nd cod nome venci ment o dat a1 610 Paul o Fer nandes Lopes 2341. 36 15/ 04/ 19962 825 Pedr o Vi ei r a 989. 24 25/ 06/ 19993 316 Mar t a Cost a Mar t i ns 1389. 17 05/ 01/ 19924 34 Rui Vasco Per ei r a 5310. 32 15/ 04/ 19965 723 J or ge Bar at a 767. 26 03/ 09/ 2002