EEL170 Computação I
3a Série de slides
Versão de 09/10/2015
Função confirmar
Em muitos programas temos de confirmar uma opção com S ou N. Vamos fazer então
uma função que retorna a escolha realizada pelo usuário.
// esta função exige o uso da unit crt
Function funConfirmar(mens: string): char;
(* Função para confirmar ou não uma opção do usuário; data: ...; Responsável: ... *)
Var
Carac: char;
Begin
repeat
Writeln(mens,’ Confirme ou não sua opção com S ou N);
Carac := upcase(readkey);
If (carac <> ‘S’) and (carac <> ‘N’)
Then Writeln(‘Opção inválida. Tente novamente’);
Until (carac = ‘S’) or (carac = ‘N’);
funConfirmar := carac;
End;
ESTRUTURAS DE DADOS
PERSISTENTES
ARQUIVOS
Arquivos nas linguagens de
programação
Arquivo: estrutura de dados persistente
Arquivos comuns nas linguagens de
programação:
Binário: acesso sequencial e direto
Texto: acesso sequencial e portabilidade
Características
• E/S: teclado, monitor e impressora podem ser considerados
arquivos do tipo texto
• Armazenamento persistente de dados: arquivos em meios
magnéticos, óticos ou eletrônicos
• Arquivo: tipo de variável
• Organização: como estão dispostas as unidades de informação no
arquivo: linear seqüencial, árvore, ...
• Formas de acesso
– Seqüencial:
– escrita das informações de forma seqüencial uma após a outra
– leitura na ordem em que as informações foram escritas
– Direto: pode-se ler/escrever em qualquer ordem
Associação
Há programas, como o editor de textos, em que o
usuário pode escolher os nomes (externos) de seus
textos.
No programa os arquivos tem um identificador
(interno)
Para cada arquivo utilizado no programa é necessário
associar o nome interno ao externo:
Antes de se usar, uma variável arquivo deve ser associada a um
identificador externo
Feita a associação, o arquivo pode ser aberto para ser lido/escrito
Arquivo texto
O arquivo deve ser do tipo texto
Após associar e abrir pode-se escrever/ler
A leitura/escrita é sequencial
Para escrever: o conteúdo de variáveis são
escritas no arquivo através de comandos
de e/s da linguagem de programação
Para ler: o conteúdo do arquivo é lido para
variáveis através de comandos de e/s da
linguagem de programação
Arquivo binário
O arquivo tipado deve ser de um tipo (estruturado)
Para ler/escrever sequencialmente:
Ler do arquivo para uma variável estruturada com o
mesmo tipo do arquivo
Escrever no arquivo os dados de uma variável
estruturada do mesmo tipo do arquivo
Para ler/escrever com acesso direto:
Posicionar o arquivo na posição em que se deseja
ler/escrever
Ler do arquivo para variável do mesmo tipo do arquivo
Escrever de variável para o arquivo
Ler e escrever em arquivo
ler
Variável arquivo
Variável transferência
escrever
Arquivo externo
eof
Ooo
0
1
2
3
4
n
Arquivos em Pascal
• Texto - <id arquivo>:text
– Organização seqüencial de caracteres
– Pode ser formatado em linhas terminadas por CR
– acesso seqüencial
• Tipado - <id arquivo>:file of <tipo do arquivo>;
– Arquivo binário
– Organização seqüencial dos componentes definidos no <tipo do
arquivo>
– Estruturado como uma sequência dos componentes nas
posições 0, 1, 2, ...
– acesso seqüencial ou direto pela posição
• Sem tipo definido - <arquivo>:file;
– Similar ao tipado, mas seus componentes não tem uma
estrutura pré-definida
Procedimentos e funções p/
arquivos
TEXTO
TIPADO
SEM TIPO
Associar
Assign
assign
assign
Abrir
Reset append
Reset
Reset
Criar
rewrite
rewrite
rewrite
Fechar
close
Close truncate
Close truncate
Escrever
Write[ln]
write
blockwrite
Ler
Read[ln]
Read
blockread
seek
seek
eof
eof
filepos
filepos
Posicionar
Teste fim arq
Posição atual
eof
Outros procedimentos e funções
• Procedimentos genéricos
–
–
–
–
–
–
Chdir(patch): mudar o diretório corrente
Erase(arquivo): destruir arquivo
Getdir(d,s): retorna o diretório corrente de um disco
Mkdir(s): cria um diretório
Rename(nomeexterno,novonome): renomear
Rmdir(s): remove um diretório vazio
• Unit do Pascal com procedimentos e funções
– dos
Exercícios de arquivos com
dados contábeis
Dados de cada movimento contábil:
Obs.: movimento contábil – movimentação de conta a débito ou a crédito
Número da conta: inteiro com 4 dígitos;
D/C: um caractere “d” ou “c” para indicar se o movimento é a débito ou a
crédito;
Valor: um real para o valor do movimento
Programas:
a) Gravar movimentos contábeis em uma matriz;
Ordenar os movimentos por ordem de conta;
Gravar um arquivo ordenado com os movimentos;
b) Dividir o arquivo obtido em “a” em dois ordenados, um com os
débitos, e outro com os créditos;
c) Concatenar os dois arquivos obtidos em “b” gerando um arquivo;
d) Realizar um merge dos dois arquivos obtidos em “b”.
Aplicação
• Problema: dar persistência a uma agenda que
foi implementada utilizando-se uma matriz, com
nome e telefone dos contatos.
• Solução: incluir dois procedimentos no
programa com acessos sequenciais:
– Abrir: no início do programa para abrir o arquivo e
copiar os dados do arquivo para a matriz
– Salvar: no fim do programa para salvar os dados da
matriz no arquivo
Aplicação
• Problema: Uma pequena instituição comercial deseja o controle do
estoque dos produtos que comercializa. Para cada produto manter:
–
–
–
–
Código: identifica o produto;
Nome: descrição sintética do produto
Preço: valor de venda;
Quantidade: quantidade em estoque
• O sistema deve permitir
– incluir um produto novo – o código é dado pelo sistema em ordem
seqüencial crescente
– Comprar um produto já existente (entrada de uma ou mais unidades)
– Vender um produto (uma ou mais unidades)
– Consultar um produto pelo código
– Listar todos os produtos de 20 em 20
– Alterar dados do produto (não pode alterar o código)
• Todas as operações são realizadas com acesso direto pelo código
Observação
Como o sistema poderá produzir o código
do produto, para facilitar vamos produzir
este código de forma sequencial a partir do
zero.
Aplicação
• Para o problema anterior:
– O usuário escolhe o código do produto, que
pode variar de 0 a 3.000.
– O usuário pode excluir um produto desde que
a quantidade do mesmo seja igual a zero.
– Todas as operações com acesso direto pelo
código a menos da listagem que será
sequencial.
Observações
- Como o maior código é 3.000, ele poderá
continuar a ser a posição da informação do
produto no arquivo, pois o arquivo não será
grande.
- Ao criar um produto verificar se o código já
existe.
- Pode-se posicionar além do fim do arquivo
para incluir um produto novo.
Aplicação
• Para o mesmo problema anterior:
– O usuário escolhe o código do produto, e este
código tem 9 (nove) dígitos numéricos,
apesar de existirem apenas 3.000 produtos
– O usuário pode excluir um produto desde que
a quantidade do mesmo seja igual a zero.
– Todas as operações com acesso direto pelo
código a menos da listagem que será
sequencial.
Observação
Como o código numérico tem nove dígitos, ele não
poderá ser a posição das informações no
arquivo, pois exigiria um arquivo com o tamanho
de 1 trilhão, para apenas 3.000 registros com
informações.
Fazer um hash para obter a posição no arquivo a
partir do código, tratando as colisões
(sinônimos).
O hash poderá ser o resto da divisão do código
por 6.001.
Abrir ou criar arquivo
Quando se trabalha com um arquivo é necessário
abri-lo para ler (arquivo já existente) ou escrever
(arquivo já existente ou ainda não).
Na maior parte dos casos de programas com
arquivos, o usuário deverá informar o
identificador externo do arquivo.
Como essas operações podem seguir um padrão
comum, será conveniente fazer um
procedimento a ser incluído em uma biblioteca.
Como há diferenças nos arquivos texto e binários,
será necessário fazer procedimentos distintos
para os arquivos texto e binários
Passos gerais para abrir/criar
Solicitar ao usuário que informe o nome que deseja dar ao
arquivo, alertando para os dados que o arquivo conterá
O programador seleciona a operação abrir ou criar novo
arquivo
O procedimento verifica se não houve erro:
No caso de “abrir” o arquivo deve existir, caso contrário há erro e o
procedimento deve ser reiniciado;
No caso de “criar novo” o arquivo não pode existir; se existir pode
haver erro e deve ser solicitado ao usuário que decida se o arquivo
deve ser realmente criado, destruindo as informações existentes, ou
então não deve ser criado, e neste caso o procedimento deve ser
reiniciado para novas opções do usuário.
Procedimento - arquivo binário
procedure abrirArqBin(arqMens: string; operac:
char; arq: file; var nomeExt: string);
(* Procedimento padrão para abrir arquivo
existente ou criar arquivo novo. Parâmetros:
mensagem para o usuário;
operação a ou c para abrir ou criar;
arquivo não tipado;
nome externo escolhido pelo usuário *)
// Uses digDados, dos, crt; // bibliotecas
var
Correto: boolean; // variável para controlar erro
Resultado: integer; // resultado da busca do arquivo
begin
repeat
correto := true; // inicia sem erro
writeln(arqMens);
digStr(‘Informar o nome completo do arquivo’, 40, 6, nomeExt);
assign(arq, nomeExt);
{$i-} // para inibir rotina de tratamento de erro
reset(arq); // tenta abrir para verificar se já existe
{$I+} // reativar tratamento de erro
resultado := ioresult;
If (operac = ‘A’) and (resultado <> 0) then
begin
writeln(‘Erro: o arquivo não existe. Escolha outro nome’);
Correto := false;
end;
If (operac = ‘C’) and (resultado = 0) then
begin
If funConfirmar (‘Atenção: o arquivo já existe!!! Deve confirmar se deve mesmo ser destruido e criado um
novo ou não’) = ‘N’ then
correto := false;
until correto;
if operac = ‘C’ then rewrite(arq);
end;
Procedimento - arquivo texto
Procedure abrirArqText(arqMens: string; operac:
char; arq: text; var nomeExt: string);
(* Procedimento padrão para abrir arquivo
existente ou criar arquivo novo. Parâmetros:
mensagem para o usuário;
operação a ou c para abrir ou criar;
arquivo texto;
nome externo escolhido pelo usuário *)
// Uses digDados, dos, crt; // bibliotecas
Var
Correto: boolean; // variável para controlar erro
Resultado: integer; // resultado da busca do arquivo
begin
repeat
correto := true; // inicia sem erro
writeln(arqMens);
digStr(‘Informar o nome completo do arquivo’, 40, 6, nomeExt);
assign(arq, nomeExt);
{$i-} // para inibir rotina de tratamento de erro
reset(arq); // tenta abrir para verificar se já existe
{$I+}
resultado := ioresult;
If (operac = ‘A’) and (resultado <> 0) then
begin
writeln(‘Erro: o arquivo não existe. Escolha outro nome’);
Correto := false;
end;
If (operac = ‘C’) and (resultado = 0) then
begin
If funConfirmar (‘Atenção: o arquivo já existe!!! Deve confirmar se deve mesmo ser destruido e criado um
novo ou não’) = ‘N’ then
correto := false;
until correto;
if operac = ‘C’ then rewrite(arq);
end;
Acesso binário
•
Uma estrutura linear ordenada segundo um item de
seus registros, permite uma busca por acesso binário
por valores desse item
–
“Chave de ordenação e de acesso”
– Nessa busca a cada acesso despreza-se metade
de seu espaço de busca
– A quantidade de acessos será proporcional ao
logaritmo na base 2 da quantidade de registros
da estrutura
•
Um arquivo binário ordenado segundo um dos itens de
seu registro – sua”chave” de ordenação – pode ser
acessado via busca binária sobre este item
Exemplo
–
Uma biblioteca com os livros dispostos no cadastro em ordem
de número crescente de ficha catalográfica. O número da ficha
é a chave do arquivo
–
Para acessar: calcular o meio do arquivo (em tamanho) e
comparar a chave do livro que se busca com a chave do meio
do arquivo. Se a chave que se busca é igual à chave do meio,
o livro foi encontrado. Se a chave buscada é maior do que a
chave do meio, o livro buscado está na metade superior do
arquivo, senão está na parte inferior. Toma-se a metade
restante e calcula-se seu meio, e se continua o processo até
encontrar a chave ou verificar que a chave não existe.
Exemplo Numérico - 1
Fichas: 21 34 54 65 70 74 85 90 95
• Procurar a ficha 54
• 54 -----------------------| meio
• Resta 21 34 54 65
• 54 -----------| meio
• Resta 54 65
• 54-------| meio
• Encontrou
Exemplo Numérico - 2
•
Fichas: 21 34 54 65 70 74 85 90 95
•
Procurar a ficha 88
•
88 ----------------------------| meio
•
Resta 74 85 90 95
•
88 -----------| meio
•
Resta 90 95
•
88-------|meio
•
Resta 95
•
Não encontrou
Algoritmo busca binária
•
Algoritmo buscaBinArquivo
•
(* algoritmo para a busca binária em um arquivo binário ordenado
pelo item “ficha” de seu registro; Responsável... Data ... *)
•
Tipo tReg: registro ficha: inteiro
•
........
•
Fim
•
Var biblioteca: file of tReg
•
Livro: tReg
•
Inicio
•
......
•
Topo ← tamanho (arquivo)
•
Base ← 1
•
Ler fichaBusca // chave de busca
•
Centro ← (topo + base) div 2 // truncar
•
Posicionar arquivo biblioteca em centro
•
Leia (biblioteca, livro)
•
Enquanto (base <= topo) e (livro.ficha <> fichaBusca) faça
–
Inicio
–
Se fichaBusca > livro.ficha
–
Então base ← centro +1
–
Senão topo ← centro -1
–
Centro ← (topo + base) div 2 // truncar
–
Posicionar arquivo biblioteca em centro
–
Leia (biblioteca, livro)
–
Fim
•
Se fichaBusca = livro.ficha
•
Então escreva (“Encontrou”, livro.ficha, …)
•
Senão escreva (“Livro não encontrado”)
•
fim
Download

Apresentação parte 3