18 Novembro 2005Leitura, Escrita e Processamento de Registos - Estruturas e Listas 1 Leitura,...

34
18 Novembro 2005 Leitura, Escrita e Proc essamento de Registos - Estruturas e Listas 1 Leitura, Escrita e Processamento de Registos Estruturas e Listas Jorge Cruz DI/FCT/UNL Programação para as Ciências Experimentais 1º Semestre 2005/2006

Transcript of 18 Novembro 2005Leitura, Escrita e Processamento de Registos - Estruturas e Listas 1 Leitura,...

Page 1: 18 Novembro 2005Leitura, Escrita e Processamento de Registos - Estruturas e Listas 1 Leitura, Escrita e Processamento de Registos Estruturas e Listas Jorge.

18 Novembro 2005 Leitura, Escrita e Processamento de Registos - Estruturas e Listas

1

Leitura, Escrita e Processamento de RegistosEstruturas e Listas

Jorge CruzDI/FCT/UNL

Programação para as Ciências Experimentais

1º Semestre 2005/2006

Page 2: 18 Novembro 2005Leitura, Escrita e Processamento de Registos - Estruturas e Listas 1 Leitura, Escrita e Processamento de Registos Estruturas e Listas Jorge.

18 Novembro 2005 Leitura, Escrita e Processamento de Registos - Estruturas e Listas

2

Registos em Ficheiros• Muita informação alfanumérica está armazenada em ficheiros,

na forma de “registos”. Por exemplo, numa base de dados de uma 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/ 1996723 J or ge Bar at a 767. 26 03/ 09/ 2002

Page 3: 18 Novembro 2005Leitura, Escrita e Processamento de Registos - Estruturas e Listas 1 Leitura, Escrita e Processamento de Registos Estruturas e Listas Jorge.

18 Novembro 2005 Leitura, Escrita e Processamento de Registos - Estruturas e Listas

3

Leitura de Ficheiros• A primeira questão a resolver consiste no tratamento dos

caracteres brancos em cadeias de caracteres. Isto porque há duas formas típicas de armazenamento dessas cadeias:

– Comprimento Fixo: As cadeias têm sempre o mesmo número de caracteres (sendo usados espaços se necessário);

– Comprimento Variável: As cadeias 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: 18 Novembro 2005Leitura, Escrita e Processamento de Registos - Estruturas e Listas 1 Leitura, Escrita e Processamento de Registos Estruturas e Listas Jorge.

18 Novembro 2005 Leitura, Escrita e Processamento de Registos - Estruturas e Listas

4

Leitura de Ficheiros• Por exemplo, “Pedro Vieira” pode ser codificado

– Comprimento Fixo: Com 5+1+6 = 12 caracteres (incluindo o espaço), mais 13 espaços, para permitir cadeias 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 horozontal (‘\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: 18 Novembro 2005Leitura, Escrita e Processamento de Registos - Estruturas e Listas 1 Leitura, Escrita e Processamento de Registos Estruturas e Listas Jorge.

18 Novembro 2005 Leitura, Escrita e Processamento de Registos - Estruturas e Listas

5

Leitura de 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ê nem caracteres brancos nem espaços. Assim, o nome “Pedro Vieira” seria lido não como 1, mas sim como 2 cadeias. 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 lidos como quaisquer outros caracteres, mas são impressos como espaços .

Page 6: 18 Novembro 2005Leitura, Escrita e Processamento de Registos - Estruturas e Listas 1 Leitura, Escrita e Processamento de Registos Estruturas e Listas Jorge.

18 Novembro 2005 Leitura, Escrita e Processamento de Registos - Estruturas e Listas

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: 18 Novembro 2005Leitura, Escrita e Processamento de Registos - Estruturas e Listas 1 Leitura, Escrita e Processamento de Registos Estruturas e Listas Jorge.

18 Novembro 2005 Leitura, Escrita e Processamento de Registos - Estruturas e Listas

7

Leitura de Ficheiros

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:

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

ou numa só instrução[cod,nome,venc,data,count]=fscanf(fid,"%i%25c%f%s","C");

610 Paulo Fernandes Lopes 2341.36 15/04/1996

Page 8: 18 Novembro 2005Leitura, Escrita e Processamento de Registos - Estruturas e Listas 1 Leitura, Escrita e Processamento de Registos Estruturas e Listas Jorge.

18 Novembro 2005 Leitura, Escrita e Processamento de Registos - Estruturas e Listas

8

Leitura de Ficheiros

Comprimento Variável:• Neste caso, 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

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

quer numa só instrução[cod,nome,venc,data,count]=fscanf(fid,"%i%s%f%s","C");

610 Paulo Fernandes Lopes 2341.36 15/04/1996

Page 9: 18 Novembro 2005Leitura, Escrita e Processamento de Registos - Estruturas e Listas 1 Leitura, Escrita e Processamento de Registos Estruturas e Listas Jorge.

18 Novembro 2005 Leitura, Escrita e Processamento de Registos - Estruturas e Listas

9

Escrita de Ficheiros• A escrita de ficheiros depende igualmente do formato utilizado

para as strings. Em comprimento fixo, o registo pode ser escrito como

fprintf(fid, "%3i", cod);

fprintf(fid, "%-25s", nome);

fprintf(fid, "%7.2f", venc);

fprintf(fid, "%11s", data);

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

ou numa só instrução, como anteriormente. Notar ainda que1. 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 linha610 Paulo Fernandes Lopes 2341.36 15/04/1996

Page 10: 18 Novembro 2005Leitura, Escrita e Processamento de Registos - Estruturas e Listas 1 Leitura, Escrita e Processamento de Registos Estruturas e Listas Jorge.

18 Novembro 2005 Leitura, Escrita e Processamento de Registos - Estruturas e Listas

10

Escrita de Ficheiros• Em comprimento variável, o registo de um empregado pode ser

escrito como fprintf(fid, "%i\t", cod);

fprintf(fid, "%s\t", nome);

fprintf(fid, "%7.2f\t", venc);

fprintf(fid, "%s\n", data);

ou numa só instrução, como anteriormente. Notar, 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.

610 Paulo Fernandes Lopes 2341.36 15/04/1996

Page 11: 18 Novembro 2005Leitura, Escrita e Processamento de Registos - Estruturas e Listas 1 Leitura, Escrita e Processamento de Registos Estruturas e Listas Jorge.

18 Novembro 2005 Leitura, Escrita e Processamento de Registos - Estruturas e Listas

11

Selecção de Registos

• Podemos agora abordar o problema colocado anteriormente: ler um ficheiro de empregados e 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.

Page 12: 18 Novembro 2005Leitura, Escrita e Processamento de Registos - Estruturas e Listas 1 Leitura, Escrita e Processamento de Registos Estruturas e Listas Jorge.

18 Novembro 2005 Leitura, Escrita e Processamento de Registos - Estruturas e Listas

12

Selecção de Registos• Eis a versão para formato fixo.

[f_in, msg_in ] = fopen("empresa_in_fix.txt", "r");[f_out, msg_out] = fopen("empresa_out_fix.txt", "w");[cod,nome,venc,data,ct] = fscanf(f_in,"%i%25c%f%s","C");while !feof(f_in) if venc > 1000 fprintf(f_out,"%3i%-25s%7.2f%11s", cod,nome,venc,data); fprintf(f_out, "%c", "\n"); endif; [cod,nome,venc,data,ct] = fscanf(f_in,"%i%25c%f%s","C"); endwhile; fclose(f_in); fclose(f_out);

Page 13: 18 Novembro 2005Leitura, Escrita e Processamento de Registos - Estruturas e Listas 1 Leitura, Escrita e Processamento de Registos Estruturas e Listas Jorge.

18 Novembro 2005 Leitura, Escrita e Processamento de Registos - Estruturas e Listas

13

Selecção de Registos• E eis a versão para formato variável.

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

[f_aux, msg] = fopen("empresa_aux_var.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 !feof(f_aux) if venc > 1000 fprintf(f_out, "%i\t%s\t%7.2f\t%s\n", cod,nome,venc,data); endif; [cod,nome, venc, data, count] = fscanf(f_aux,"%i%s%f%s","C"); endwhile; fclose(f_aux); fclose(f_out);

Page 14: 18 Novembro 2005Leitura, Escrita e Processamento de Registos - Estruturas e Listas 1 Leitura, Escrita e Processamento de Registos Estruturas e Listas Jorge.

18 Novembro 2005 Leitura, Escrita e Processamento de Registos - Estruturas e Listas

14

Processamento de Registos

• Podemos agora considerar outro tipo de processamento de registos, 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. Em ambos os casos apenas apresentamos a versão para formato variável.

• De notar a instrução printf, que permite escrever no terminal mensagens formatadas (com os formatos usados em ficheiros).

Page 15: 18 Novembro 2005Leitura, Escrita e Processamento de Registos - Estruturas e Listas 1 Leitura, Escrita e Processamento de Registos Estruturas e Listas Jorge.

18 Novembro 2005 Leitura, Escrita e Processamento de Registos - Estruturas e Listas

15

Processamento de Registos• 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 ao quociente total/i).

rem_sp("empresa_in_var.txt", "empresa_aux_var.txt"); [f_aux, msg] = fopen("empresa_aux_var.txt", "r"); [cod,nome, venc, data, count] = fscanf(f_aux,"%i%s%f%s","C"); i = 0; total = 0; while !feof(f_aux) i = i+1; total = total +venc; [cod,nome, venc, data, count] = fscanf(f_aux,"%i%s%f%s","C"); endwhile; printf("o total dos vencimentos é de %7.2f \n", total); printf("a média dos vencimentos é de %7.2f \n",total/i); fclose(f_aux); fclose(f_out);

Page 16: 18 Novembro 2005Leitura, Escrita e Processamento de Registos - Estruturas e Listas 1 Leitura, Escrita e Processamento de Registos Estruturas e Listas Jorge.

18 Novembro 2005 Leitura, Escrita e Processamento de Registos - Estruturas e Listas

16

Processamento de Registos• O tratamento de datas, implica reconhecer quando uma data é

anterior a outra, o que é feito com a função anterior que compara duas datas, sendo armazenada a data menor.

rem_sp("empresa_in_var.txt", "empresa_aux_var.txt"); [f_aux, msg] = fopen("empresa_aux_var.txt", "r"); [cod,nome, venc, data, count] = fscanf(f_aux,"%i%s%f%s","C"); data_menor =“01/01/2100”; while !feof(f_aux) if anterior(data,data_menor) data_menor = data; endif; [cod,nome, venc, data, count] = fscanf(f_aux,"%i%s%f%s","C"); endwhile; printf("a entrada mais antiga foi em %s\n",data_menor); fclose(f_aux); fclose(f_out);

Page 17: 18 Novembro 2005Leitura, Escrita e Processamento de Registos - Estruturas e Listas 1 Leitura, Escrita e Processamento de Registos Estruturas e Listas Jorge.

18 Novembro 2005 Leitura, Escrita e Processamento de Registos - Estruturas e Listas

17

Processamento de Registos• A comparação de datas é feita através da comparação dos seus

anos, meses e dias, tendo o cuidado de converter as cadeias de caracteres em números.

function d = anterior(data1,data2);% data no formato dd/mm/aaaa ano1 = str2num(substr(data1,7,4)); ano2 = str2num(substr(data2,7,4)); if ano1<ano2 d = 1; elseif ano1 > ano2 d = 0; else mes1 = str2num(substr(data1,4,2)); mes2 = str2num(substr(data2,4,2)); if mes1<mes2 d = 1; elseif mes1 > mes2 d = 0; else dia1 = str2num(substr(data1,1,2)); dia2 = str2num(substr(data2,1,2)); if dia1 < dia2 d = 1; else d = 0; endif; endif; endif; endfunction

Page 18: 18 Novembro 2005Leitura, Escrita e Processamento de Registos - Estruturas e Listas 1 Leitura, Escrita e Processamento de Registos Estruturas e Listas Jorge.

18 Novembro 2005 Leitura, Escrita e Processamento de Registos - Estruturas e Listas

18

Processamento de Registos

• Neste último caso, a informação transmitida não é muito interessante. Provavelmente estaremos mais interessados em saber quem é o empregado mais antigo, ou seja, qual o nome do empregado com data de entrada mais antiga.

• Este problema pode ser resolvido com uma pequena adaptação do código, guardando não só a data mais antiga como o nomewhile !feof(f_aux) if anterior(data,m_data) data_menor = data; antigo = nome endif; [cod,nome, venc, data, count] = ...endwhile;printf("o empregado mais antigo é %s \n", antigo);printf("com data de entrada %s \n", data_menor);

Page 19: 18 Novembro 2005Leitura, Escrita e Processamento de Registos - Estruturas e Listas 1 Leitura, Escrita e Processamento de Registos Estruturas e Listas Jorge.

18 Novembro 2005 Leitura, Escrita e Processamento de Registos - Estruturas e Listas

19

Processamento de Registos

• Todos estes programas obrigam a ler um ficheiro, cada vez que se pretende responder a uma questão.

• No entanto, a leitura 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.

Page 20: 18 Novembro 2005Leitura, Escrita e Processamento de Registos - Estruturas e Listas 1 Leitura, Escrita e Processamento de Registos Estruturas e Listas Jorge.

18 Novembro 2005 Leitura, Escrita e Processamento de Registos - Estruturas e Listas

20

Processamento de Informação Alfanumérica• Podemos considerar que a informação dos ficheiros de

registos corresponde a uma tabela. Esta tabela é constituída por uma sequência de “registos”, um em cada linha.

• Se toda a informação fosse numérica, isto é se cada registo tivesse n “campos”, ela poderia ser guardada numa matriz com m linhas, uma linha para cada registo de n posições.

• Em Octave, existe um problema: uma posição de uma matriz não pode ser ocupada por uma cadeia de caracteres!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 21: 18 Novembro 2005Leitura, Escrita e Processamento de Registos - Estruturas e Listas 1 Leitura, Escrita e Processamento de Registos Estruturas e Listas Jorge.

18 Novembro 2005 Leitura, Escrita e Processamento de Registos - Estruturas e Listas

21

Processamento de Informação Alfanumérica• Desta forma a informação de uma tabela alfanumérica não

pode ser guardada como uma matriz. Vamos ver como se podem ultrapassar estes problemas em Octave, fazendo-o em duas “fases”:

– Como representar um registo heterogéneo, com vários campos de diferentes tipos, alguns alfanuméricos.

– Como armazenar e aceder a vários destes registos heterogéneos.

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 22: 18 Novembro 2005Leitura, Escrita e Processamento de Registos - Estruturas e Listas 1 Leitura, Escrita e Processamento de Registos Estruturas e Listas Jorge.

18 Novembro 2005 Leitura, Escrita e Processamento de Registos - Estruturas e Listas

22

Estruturas

• Vectores e Matrizes são muito úteis quando os dados são todos do mesmo tipo (no Octave, de qualquer tipo numérico).

• No entanto, em muitos casos, a informação que se pretende agrupar com um só identificador não é do mesmo tipo.

• Por exemplo, um empregado duma empresa pode ter associado a 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)

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

Page 23: 18 Novembro 2005Leitura, Escrita e Processamento de Registos - Estruturas e Listas 1 Leitura, Escrita e Processamento de Registos Estruturas e Listas Jorge.

18 Novembro 2005 Leitura, Escrita e Processamento de Registos - Estruturas e Listas

23

Estruturas

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

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

Page 24: 18 Novembro 2005Leitura, Escrita e Processamento de Registos - Estruturas e Listas 1 Leitura, Escrita e Processamento de Registos Estruturas e Listas Jorge.

18 Novembro 2005 Leitura, Escrita e Processamento de Registos - Estruturas e Listas

24

Estruturas• As estruturas são compostas por vários campos, cada um

com um nome. Na estrutura para representação da informação de empregados, consideraremos os campos abaixo, que guardam a informação “esperada”

– cod: o código do empregado

– nome: o nome do empregado

– venc: o vencimento do empregado

– data: a data de entrada do empregado na empresa.

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

Page 25: 18 Novembro 2005Leitura, Escrita e Processamento de Registos - Estruturas e Listas 1 Leitura, Escrita e Processamento de Registos Estruturas e Listas Jorge.

18 Novembro 2005 Leitura, Escrita e Processamento de Registos - Estruturas e Listas

25

Estruturas• 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:

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

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

Page 26: 18 Novembro 2005Leitura, Escrita e Processamento de Registos - Estruturas e Listas 1 Leitura, Escrita e Processamento de Registos Estruturas e Listas Jorge.

18 Novembro 2005 Leitura, Escrita e Processamento de Registos - Estruturas e Listas

26

Estruturas• De notar que os campos de uma estrutura não são ordenados,

e podem ser preenchidos por qualquer ordem.

• Assim a estrutura que temos referido

pode ser inicializada quer com a sequência de instruções empregado.data=“15/04/1996”;empregado.cod = 610;empregado.nome = “Paulo Fernandes Lopes”;empregado.venc = 2341.36;

ou com outra sequência empregado.venc = 2341.36;

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

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

Page 27: 18 Novembro 2005Leitura, Escrita e Processamento de Registos - Estruturas e Listas 1 Leitura, Escrita e Processamento de Registos Estruturas e Listas Jorge.

18 Novembro 2005 Leitura, Escrita e Processamento de Registos - Estruturas e Listas

27

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

if emp_610.venc > 1000 then disp(emp_610.nome)

endif

• No entanto este tipo de processamento só é verdadeiramente útil se tivermos a possibilidade de aceder a todos os empregados de uma forma genérica.

Page 28: 18 Novembro 2005Leitura, Escrita e Processamento de Registos - Estruturas e Listas 1 Leitura, Escrita e Processamento de Registos Estruturas e Listas Jorge.

18 Novembro 2005 Leitura, Escrita e Processamento de Registos - Estruturas e Listas

28

Estruturas• Por exemplo, se tivéssemos 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:for i = 1:n

if tabela(i,2) > 1000 then disp(tabela(i,1))

endif endfor;

• Por analogia, o que é necessário é poder aceder a uma sequência de (1 a n) estruturas do tipo da do empregado.

• Em Octave, essa sequência pode ser implementada através de listas.

1 2

1 610 2341. 362 825 989. 243 316 1389. 174 34 5310. 325 723 767. 26... . . . . . .

Page 29: 18 Novembro 2005Leitura, Escrita e Processamento de Registos - Estruturas e Listas 1 Leitura, Escrita e Processamento de Registos Estruturas e Listas Jorge.

18 Novembro 2005 Leitura, Escrita e Processamento de Registos - Estruturas e Listas

29

Listas• Uma lista é uma sequência de dados do mesmo tipo, simples

ou complexo, para as quais estão definidas as operações de:

• Criação: list(elem_1, elem_2, ..., elem_k)

– Cria uma lista, com os elementos de 1 a k (ou uma lista vazia se k = 0)

• Acrescento: append(nome_lista,elem_1, ...,elem_k)

– Acrescenta os os elementos de 1 a k à lista com o nome indicado no 1º argumento

• Acesso: nth(nome_lista, k)

– Acede ao k-ésimo elemento da lista. De notar que esse elemento pode ser uma estrutura arbitrariamente complexa.

Page 30: 18 Novembro 2005Leitura, Escrita e Processamento de Registos - Estruturas e Listas 1 Leitura, Escrita e Processamento de Registos Estruturas e Listas Jorge.

18 Novembro 2005 Leitura, Escrita e Processamento de Registos - Estruturas e Listas

30

Listas• Para ilustrar estes conceitos, vamos ler um ficheiro com

informação sobre empregados e criar uma lista com essa informação.

• A instrução principal consiste em criar uma estrutura, emp, e atribuir-lhe os valores lidos do ficheiro (a formatação dos campos é feita como anteriormente).

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

• Para além destas instruções, são necessárias instruções para inicializar a lista e para a ir acrescentando com os empregados lidos. O número de empregados também é computado.

Page 31: 18 Novembro 2005Leitura, Escrita e Processamento de Registos - Estruturas e Listas 1 Leitura, Escrita e Processamento de Registos Estruturas e Listas Jorge.

18 Novembro 2005 Leitura, Escrita e Processamento de Registos - Estruturas e Listas

31

Listas• Eis o programa completo, que cria uma lista, tab_empregados, com a informação sobre os empregados inicialmente no ficheiro “empresa_aux_var.txt”.

[f_aux, msg] = fopen("empresa_aux_var.txt", "r"); tab_empregados = list(); n = 0; [emp.cod,emp.nome,emp.venc,emp.data, count] = fscanf(f_aux,"%i%s%f%s","C"); while !feof(f_aux) n = n+1; tab_empregados = append(tab_empregados, emp); [emp.cod,emp.nome,emp.venc,emp.data, count] = fscanf(f_aux,"%i%s%f%s","C"); endwhile; fclose(f_aux);

Page 32: 18 Novembro 2005Leitura, Escrita e Processamento de Registos - Estruturas e Listas 1 Leitura, Escrita e Processamento de Registos Estruturas e Listas Jorge.

18 Novembro 2005 Leitura, Escrita e Processamento de Registos - Estruturas e Listas

32

Listas

• A partir deste momento, todo o processamento da informação sobre os empregados pode ser feito sem leitura do ficheiro, mas apenas por acesso à lista “tab_empregados”.

• Se já tiver sido lida a informação dos empregados para a lista “tab_empregados”, com n elementos, ela pode ser acedida directamente, sem necessidade de nova leitura do ficheiro.

total = 0; for i = 1:n total = total + nth(tab_empregados,i).venc; endfor; printf("o total de vencimentos é %7.2f \n“, total); printf(“ e a sua média é %7.2f \n", total/n);

Page 33: 18 Novembro 2005Leitura, Escrita e Processamento de Registos - Estruturas e Listas 1 Leitura, Escrita e Processamento de Registos Estruturas e Listas Jorge.

18 Novembro 2005 Leitura, Escrita e Processamento de Registos - Estruturas e Listas

33

Listas

• Igualmente se podem escrever o nome e vencimento dos empregados que ganham mais de 1000 euros, sem necessidade de leitura do ficheiro, mas apenas usando a mesma lista “tab_empregados”, com n elementos.

printf("Lista de empregados com mais de 1000 €: \n"); for i = 1:n emp = nth(tab_empregados,i); if emp.venc > 1000 printf("\t%s\t%7.2f\t\n",emp.nome,emp.venc); endif; endfor;

Page 34: 18 Novembro 2005Leitura, Escrita e Processamento de Registos - Estruturas e Listas 1 Leitura, Escrita e Processamento de Registos Estruturas e Listas Jorge.

18 Novembro 2005 Leitura, Escrita e Processamento de Registos - Estruturas e Listas

34

Estruturas e Listas em Funções• Estruturas e listas podem ser retornadas como resultado de uma

função. Por exemplo, a leitura de um ficheiro com o formato considerado pode ser feita pela função (que também retorna o número de elementos):

function [t, n] = ler_tabela(ficheiro); [f_aux, msg] = fopen(ficheiro, "r"); tab_empregados = list(); n = 0; [emp.cod,emp.nome,emp.venc,emp.data, count] = fscanf(f_aux,"%i%s%f%s","C"); while !feof(f_aux) n = n+1; tab_empregados = append(tab_empregados, emp); [emp.cod,emp.nome,emp.venc,emp.data, count] = fscanf(f_aux,"%i%s%f%s","C"); endwhile; fclose(f_aux); t = tab_empregados;endfunction;