Função confirmarEm 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
repeatWriteln(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: interoperabilidade/portabilidade
Arquivos• 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• Antes de se usar, uma variável arquivo deve ser associada a um
identificador externo: mecanismo para que um arquivo possa ser associado a diferentes identificadores externos
• Feita a associação, o arquivo deve ser aberto para ser lido/escrito• Organização: como estão dispostas as unidades de informação no
arquivo: linear seqüencial, árvore, ...• Formas de acesso
– Seqüencial: leitura/escrita das informações seqüencial um após o outro– direto: pode-se ler/escrever em qualquer ordem
Ler e escrever em arquivo
Variável arquivo
Variável transferência
Arquivo externo
eofO o o
0 1 2 3 4 n
ler
escrever
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
Posicionar seek seek
Teste fim arq eof eof eof
Posição atual filepos filepos
Tamanho arq filesize filesize
Resultado E/S ioresult ioresult ioresult
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éditoNú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 implementada utilizando-se uma matriz de 100 posições, com nome e telefone dos contatos.
• Solução: incluir dois procedimentos no programa com acessos seqüenciais:– 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.
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; // bibliotecasVarCorreto: boolean; // variável para controlar erroResultado: 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;
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; // bibliotecasVarCorreto: boolean; // variável para controlar erroResultado: 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• 54 ----------------------------|• Resta 21 34 54 65• 54 -----------|• Resta 54 65• 54-------|• Encontrou
Exemplo Numérico - 2
• Fichas: 21 34 54 65 70 74 85 90 95• 88 ----------------------------|• Resta 74 85 90 95• 88 -----------|• Resta 90 95• 88-------|• 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
Top Related