UFRJ-CCMN-INSTITUTO
DE MATEMÁTICA
Departamento de Ciência da Computação
ARQUIVOS
EM PASCAL - Prof. Miguel Jonathan
Este texto apresenta alguns
exemplos que esclarecem o uso de arquivos em Pascal.
1. Arquivos texto:
São arquivos que contêm strings e caracteres.. O formato é
uma sequência de caracteres separados por marcas de fim-de-linha.
O exemplo abaixo permite ler linhas do teclado (texto) de tamanhos
variados, para um arquivo de nome escolhido pelo usuário.
O arquivo é sempre re-criado com rewrite(f)
e o texto é
gravado caractere a caractere. A tecla ENTER gera um caractere de fim-de-linha,
que é inserido normalmente no texto gravado. O laço de repetição interromperá
quando for lido e gravado o caractere de numero 26 na tabela de caracteres
ASCII, representado em Pascal por #26, que é uma forma equivalente a
chr(26).
Depois d egravado, o arquivo é reaberto, desta vez para leitura
não-destrutiva com reset(f), e agora o arquivo é lido linha a
linha, usando o procedimento readln(f,s)dentro de um laço de repetição
controlado pela função eof(f). Essa função retorna true
somente após ser lido o último caractere.
program
textos;
var
nome_arq: string;
f:text;
c:char;
s: string;
begin
writeln ('Digite o nome do arquivo a
criar');
readln(nome_arq);
writeln('Digite seu texto para ser
gravado no arquivo ', nome_arq);
writeln ('Termine com CTRL-Z seguido de
ENTER');writeln;
assign (f, nome_arq);
rewrite(f);
repeat
read(c);
write(f,c)
until c=#26; {equivale a chr(26), que e'
CTRL-Z}
close(f);
writeln('Agora observe o arquivo ',
nome_arq, ' no seu diretorio');
writeln;
writeln ('Lendo agora do disco linha a
linha e colocando na tela:");
reset(f); {abrindo para leitura}
while (not eof(f)) do
begin
readln(f,s);
writeln(s);
end;
end.
2.
Arquivos formatados:
São arquivos que contém texto representando números
e/ou caracteres, representados no formato usado para entrada de dados pelo
teclado com read() e readln(). Não é a forma mais eficiente de
gravar números (em binário ocupa bem menos espaço) mas em muitos casos pode ser
de utilidade.
No exemplo abaixo, é gravado no arquivo arqtest.dat
30 reais gerados aleatoriamente entre 0 e 6900/7. (A função random(n)exige
argumento inteiro, para gerar um número aleatório entre 0 e n. A divisão por 7
é para gerar um real.). Como é greado com writeln(f,
...) o efeito é
colocar no arquivo uma imagem do seria impresso na tela com apenas writeln(...)
, ou seja, os caracteres correspondentes à representação dos números no formato
escolhido (8 colunas, com 2 casas decimais). Depois o arquivo é reiniciado para
leitura, e os números são lidos do arquivo exatamente como seriam do teclado se
fossem digitados nesse formato. A função eof(f)também retorna true após o
úlitmo número ter sido lido do arquivo. Assim como no teclado, a leitura ignora
espaços entre os números.
program p;
uses crt;
{testa arquivos
de reais}
var
f: text;
x: real;
i:integer;
begin
clrscr;
randomize;
assign(f, 'arqtest.dat');
rewrite(f);
for i:=1
to 30 do write(f, random(6900)/7:8:2);
reset(f);
while
not eof(f) do
begin
read(f,x);
write(x:8:2); {mostra na tela}
end;
readln;
end.
3.
Arquivos de registros:
Neste exemplo, são gravados em forma binária uma
sequência de elementos de um determinado tipo. Esse tipo pode ser qualquer tipo
básico da linguagem, como integer, real, char, boolean, ou um tipo definido
pelo programador, com um record ou um array. Nesse caso não há separadores de
linha, e a leitura e gravação são feitas com uso dos procedimentos read(f,...) e write(f,...) não sendo permitido usar readln() e writeln().
No exemplo, é definidos um tipo de registro, rec para nomes.dat. Os registros associam uma "chave", o número de inscrição DRE
do aluno, ao seu nome. . O arquivos é definido como sendo file of rec1.
Esse programa é um pouco mais elaborado. Ele permite que o
mesmo programa seja usado tanto no caso do arquivo não existir, como no caso de
já existir. Para isso, o programa usa um artifício, que é a "diretiva de
compilação" {$I-}. Diretivas de compilação orientam o
compilador a gerar programas objeto com características especiais. Elas sempre
têm a forma de um comentário entre chaves, contendo um cifrão seguido de uma
letra e o sinal - ou +. A letra indica a diretiva, nocao I indica "entrada
e saída". O sinal - indica que a partir desse ponto o programa
"desliga" a sua capacidade de abortar em caso de ocorrer um erro de
entrada ou saida de dados. A partir da linha seguinte a {$I+} essa
capacidade de abortar volta a funcionar.
O truque aqui é tentar ler um arquivo que ainda não pode não
existir ainda, com reset(f1). Se ele não existir, dará erro de
entrada/saida, mas o programa não abortará, por causa da diretiva. Em vez
disso, o efeito será tornar uma variável especial do Pascal, de nome IOResult
com um valor diferente de zero, ou zero se não tiver havido erro. Essa variável
é testada, e se for diferente de zero, então se usa rewrite(f1) sem
perigo. Em qualquer dos casos, a função seek(f1,
n) é usada
para posicionar o arquivo para gravar após o último registro. Essa função
posiciona o arquivo no registro n, no caso será filesize(f1), que dá o número de registros do
arquivo. Se for um arquivo novo, n=0, e seek(f1,0) equivale a reset(f1). Portanto
o mesmo programa pode ser usado para criar o arquivo, ou adicioanr registros ao
arquivo se já existir, sem que o usuário tenha que se preocupar com isso.
O programa pede para o usuário entrar com dados pelo teclado, e ir
gravando, em um laço controlados pela função eof(f1).
Essa função deve
retornar true quando chegar ao fim do arquivo, e nesse caso o arquivo de
entrada é o próprio tecaldo. O sinal de fim de arquivo do teclado é dado quando
se tecla CTRL-Z.
Depois de gravar os registros, o arquivo é reiniciado com reset(f1)e
seus dados são lidos para um vetor vet1
de registros do
mesmo tipo rec1.. O vetor é então ordenado pelo campo de DRE, usando um algoritmo
simples de ordenação por seleção, e os registros são regravados e listados na
tela em ordem de DRE.
program
arquivo1;
(****************************************************************
Este programa cria um arquivo nomes.dat no diretorio corrente.
Caso o arquivo nao exista, ele sera' criado, caso ja' exista
será aberto, e os registros trazidos para o vetor vet1.
O programa pede para incluir registros contendo o DRE e o nome
de alunos, um em cada linha. Terminar com CTRL-Z (fim de arquivo
pelo teclado). O vetor é entao ordenado pelo campo DRE, e o
arquivo e' totalmente re-gravado com o conteudo do vetor.
A seguir o arquivo e' reaberto para leitura com reset(), e cada
registro e' lido e seus campos impressos na tela.
ATENCAO: este programa nao funcionara' se a unit CRT for usada,
pois nesse caso CTRL-Z nao mais sera' equivalente a um fim de
arquivo.
Versao corrigida em 12/3/2002. O algoritmo de ordenacao por
selecao continha um erro na versao anterior.
*****************************************************************)
type rec1 =
record
dre: string;
nome: string;
end;
var
f1: file of rec1;
r1, temp: rec1;
vet1: array [1..50] of rec1;
i,j, posmenor,n1: integer;
begin
assign(f1, 'nomes.dat');
{$I-}
reset(f1);
if IOResult <> 0 then rewrite(f1);
seek(f1, filesize(f1)); {posiciona-se no fim
do arquivo}
{$I+}
writeln('Digite novos registros do arquivo na forma:');
writeln(' DRE');
writeln(' NOME');
while not eof(input) do
with r1 do
begin
readln (dre);
readln(nome);
write(f1,r1);
end;
close (f1);
{ Lendo o conteudo de f1 para o vetor vet1 na memoria
...}
reset (f1);
n1:= 0;
while not eof(f1) and (n1 < 50) do
begin
n1:=n1+1;
read (f1, vet1 [n1] );
end; { vet1 vai conter os n1 registros
do arquivo f1}
{ordenando f1...pelo algoritmo de selecao}
for i:=1 to n1 do
begin
posmenor:= i;
for j:=i+1 to n1 do
if vet1[j].dre <
vet1[posmenor].dre then posmenor:=j;
if posmenor<> i then
begin
temp:=vet1[i];
vet1[i]:=vet1[posmenor];
vet1[posmenor]:= temp;
end;
end;
{re-gravando os registros ordenados em f1...}
rewrite(f1); i:= 0;
for i:= 1 to n1 do write (f1, vet1[i]);
{lendo e imprimindo na tela o conteudo de f1...}
reset(f1);
while not eof(f1) do
begin
read(f1,r1) ;
with r1 do writeln (dre,'':3,nome);
end;
writeln;
close(f1);
end.