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
18 Novembro 2005
Leitura, Escrita e Processamento de
Registos - Estruturas e Listas
1
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
610
825
316
34
723
18 Novembro 2005
nome
Paulo Fernandes Lopes
Pedro Vieira
Marta Costa Martins
Rui Vasco Pereira
Jorge Barata
vencimento
data
2341.36
989.24
1389.17
5310.32
767.26
15/04/1996
25/06/1999
05/01/1992
15/04/1996
03/09/2002
Leitura, Escrita e Processamento de
Registos - Estruturas e Listas
2
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
610
825
316
34
723
18 Novembro 2005
nome
Paulo Fernandes Lopes
Pedro Vieira
Marta Costa Martins
Rui Vasco Pereira
Jorge Barata
vencimento
data
2341.36
989.24
1389.17
5310.32
767.26
15/04/1996
25/06/1999
05/01/1992
15/04/1996
03/09/2002
Leitura, Escrita e Processamento de
Registos - Estruturas e Listas
3
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
610
825
316
34
723
18 Novembro 2005
nome
Paulo Fernandes Lopes
Pedro Vieira
Marta Costa Martins
Rui Vasco Pereira
Jorge Barata
vencimento
data
2341.36
989.24
1389.17
5310.32
767.26
15/04/1996
25/06/1999
05/01/1992
15/04/1996
03/09/2002
Leitura, Escrita e Processamento de
Registos - Estruturas e Listas
4
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 .
18 Novembro 2005
Leitura, Escrita e Processamento de
Registos - Estruturas e Listas
5
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;
18 Novembro 2005
Leitura, Escrita e Processamento de
Registos - Estruturas e Listas
6
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,
[nome,
[venc,
[data,
count]
count]
count]
count]
=
=
=
=
fscanf(fid,"%i","C");
fscanf(fid,"%25c","C");
fscanf(fid,"%f","C");
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
18 Novembro 2005
2341.36
Leitura, Escrita e Processamento de
Registos - Estruturas e Listas
15/04/1996
7
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,
[nome,
[venc,
[data,
count]
count]
count]
count]
=
=
=
=
fscanf(fid,"%i","C");
fscanf(fid,"%s","C");
fscanf(fid,"%f","C");
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
18 Novembro 2005
2341.36
Leitura, Escrita e Processamento de
Registos - Estruturas e Listas
15/04/1996
8
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,
fprintf(fid,
fprintf(fid,
fprintf(fid,
fprintf(fid,
"%3i", cod);
"%-25s", nome);
"%7.2f", venc);
"%11s", data);
"%c", “\n”);
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
610 Paulo Fernandes Lopes
18 Novembro 2005
2341.36 15/04/1996
Leitura, Escrita e Processamento de
Registos - Estruturas e Listas
9
Escrita de Ficheiros
•
Em comprimento variável, o registo de um empregado pode ser
escrito como
fprintf(fid,
fprintf(fid,
fprintf(fid,
fprintf(fid,
"%i\t", cod);
"%s\t", nome);
"%7.2f\t", venc);
"%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
18 Novembro 2005
Paulo Fernandes Lopes
2341.36
Leitura, Escrita e Processamento de
Registos - Estruturas e Listas
15/04/1996
10
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.
18 Novembro 2005
Leitura, Escrita e Processamento de
Registos - Estruturas e Listas
11
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);
18 Novembro 2005
Leitura, Escrita e Processamento de
Registos - Estruturas e Listas
12
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);
18 Novembro 2005
Leitura, Escrita e Processamento de
Registos - Estruturas e Listas
13
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).
18 Novembro 2005
Leitura, Escrita e Processamento de
Registos - Estruturas e Listas
14
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);
18 Novembro 2005
Leitura, Escrita e Processamento de
Registos - Estruturas e Listas
15
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);
18 Novembro 2005
Leitura, Escrita e Processamento de
Registos - Estruturas e Listas
16
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
18 Novembro 2005
Leitura, Escrita e Processamento de
Registos - Estruturas e Listas
17
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 nome
while !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);
18 Novembro 2005
Leitura, Escrita e Processamento de
Registos - Estruturas e Listas
18
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.
18 Novembro 2005
Leitura, Escrita e Processamento de
Registos - Estruturas e Listas
19
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
610
825
316
34
723
18 Novembro 2005
nome
Paulo Fernandes Lopes
Pedro Vieira
Marta Costa Martins
Rui Vasco Pereira
Jorge Barata
vencimento
data
2341.36
989.24
1389.17
5310.32
767.26
15/04/1996
25/06/1999
05/01/1992
15/04/1996
03/09/2002
Leitura, Escrita e Processamento de
Registos - Estruturas e Listas
20
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
610
825
316
34
723
18 Novembro 2005
nome
Paulo Fernandes Lopes
Pedro Vieira
Marta Costa Martins
Rui Vasco Pereira
Jorge Barata
vencimento
data
2341.36
989.24
1389.17
5310.32
767.26
15/04/1996
25/06/1999
05/01/1992
15/04/1996
03/09/2002
Leitura, Escrita e Processamento de
Registos - Estruturas e Listas
21
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
610 Paulo Fernandes Lopes
18 Novembro 2005
venc
2341.36
Leitura, Escrita e Processamento de
Registos - Estruturas e Listas
data
15/04/1996
22
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.
emp_610 =
18 Novembro 2005
cod
nome
610 Paulo Fernandes Lopes
venc
2341.36
Leitura, Escrita e Processamento de
Registos - Estruturas e Listas
data
15/04/1996
23
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.
emp_610 =
18 Novembro 2005
cod
nome
610 Paulo Fernandes Lopes
venc
2341.36
Leitura, Escrita e Processamento de
Registos - Estruturas e Listas
data
15/04/1996
24
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”;
emp_610 =
18 Novembro 2005
cod
nome
610 Paulo Fernandes Lopes
Leitura, Escrita e Processamento de
Registos - Estruturas e Listas
venc
2341.36
data
15/04/1996
25
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
emp_610 =
cod
nome
610 Paulo Fernandes Lopes
venc
2341.36
data
15/04/1996
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”;
18 Novembro 2005
Leitura, Escrita e Processamento de
Registos - Estruturas e Listas
26
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.
18 Novembro 2005
Leitura, Escrita e Processamento de
Registos - Estruturas e Listas
27
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
1
2
instrução iterativa:
for i = 1:n
if tabela(i,2) > 1000
then disp(tabela(i,1))
endif
endfor;
1
2
3
4
5
...
610
825
316
34
723
...
2341.36
989.24
1389.17
5310.32
767.26
...
• 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.
18 Novembro 2005
Leitura, Escrita e Processamento de
Registos - Estruturas e Listas
28
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.
18 Novembro 2005
Leitura, Escrita e Processamento de
Registos - Estruturas e Listas
29
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.
18 Novembro 2005
Leitura, Escrita e Processamento de
Registos - Estruturas e Listas
30
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);
18 Novembro 2005
Leitura, Escrita e Processamento de
Registos - Estruturas e Listas
31
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);
18 Novembro 2005
Leitura, Escrita e Processamento de
Registos - Estruturas e Listas
32
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;
18 Novembro 2005
Leitura, Escrita e Processamento de
Registos - Estruturas e Listas
33
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;
18 Novembro 2005
Leitura, Escrita e Processamento de
Registos - Estruturas e Listas
34
Download

Fig. 1.1